mail.coreboot.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
List overview
Download
coreboot-gerrit
September 2020
----- 2024 -----
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
coreboot-gerrit@coreboot.org
1 participants
2628 discussions
Start a n
N
ew thread
Change in coreboot[master]: mb/siemens/mc_apl2/gpio: Undo set DRIVER for GPO
by Maxim Polyakov (Code Review)
10 Sep '20
10 Sep '20
Maxim Polyakov has uploaded this change for review. (
https://review.coreboot.org/c/coreboot/+/44469
) Change subject: mb/siemens/mc_apl2/gpio: Undo set DRIVER for GPO ...................................................................... mb/siemens/mc_apl2/gpio: Undo set DRIVER for GPO GPIO Driver mode is used for configuration interrupt routing for external devices through GPI. But there is no point in configuring this for GPO. This patch replaces the PAD_CFG_GPO_GPIO_DRIVER macro with others that do not set the corresponding bit in the Host Software Pad Ownership register. Change-Id: I406a08e526a6c655f38e4c0a355957c98e93881c Signed-off-by: Maxim Polyakov <max.senia.poliak(a)gmail.com> --- M src/mainboard/siemens/mc_apl1/variants/mc_apl2/gpio.c 1 file changed, 18 insertions(+), 18 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/69/44469/1 diff --git a/src/mainboard/siemens/mc_apl1/variants/mc_apl2/gpio.c b/src/mainboard/siemens/mc_apl1/variants/mc_apl2/gpio.c index aa4a906..9c1d79a 100644 --- a/src/mainboard/siemens/mc_apl1/variants/mc_apl2/gpio.c +++ b/src/mainboard/siemens/mc_apl1/variants/mc_apl2/gpio.c @@ -74,7 +74,7 @@ /* SDCARD_WP_1V8 */ PAD_CFG_GPI_GPIO_DRIVER(GPIO_186, DN_20K, DEEP), /* SD_PWR_EN_1V8 - Always enabled SDCard. */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_183, 0, DEEP, UP_20K), + PAD_CFG_TERM_GPO(GPIO_183, 0, UP_20K, DEEP) /* West Community */ @@ -208,15 +208,15 @@ /* EDP_VDD_EN_1V8 (DNI) - Alternative stuffing option for * PTN3460 LVDS_VDD_EN. */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_196, 1, DEEP, UP_20K), + PAD_CFG_TERM_GPO(GPIO_196, 1, UP_20K, DEEP) /* EDP_BKLT_EN_1V8 (DNI) - Alternative stuffing option for * PTN3460 LVDS_BKLT_EN */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_197, 1, DEEP, UP_20K), + PAD_CFG_TERM_GPO(GPIO_197, 1, UP_20K, DEEP) /* EDP_BKLT_CTRL_1V8 - Alternative stuffing option for * PTN3460 LVDS_BKLT_CTRL */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_198, 1, DEEP, UP_20K), + PAD_CFG_TERM_GPO(GPIO_198, 1, UP_20K, DEEP) /* DDI1_HPD# - Connect to DP1_HPD Hot plug detection signal of SMARC * Connector. @@ -263,8 +263,8 @@ /* Not connected */ PAD_CFG_NF(PMIC_PWRGOOD, UP_20K, DEEP, NF1), - PAD_CFG_GPO_GPIO_DRIVER(GPIO_214, 1, DEEP, DN_20K), - PAD_CFG_GPO_GPIO_DRIVER(GPIO_215, 1, DEEP, DN_20K), + PAD_CFG_TERM_GPO(GPIO_214, 1, DN_20K, DEEP), + PAD_CFG_TERM_GPO(GPIO_215, 1, DN_20K, DEEP), /* THERMTRIP_1V8# - Connected to CPLD */ PAD_CFG_NF_IOSSTATE_IOSTERM(PMIC_THERMTRIP_B, UP_20K, DEEP, NF1, TxLASTRxE, SAME), @@ -390,15 +390,15 @@ /* OTG_SEL_1V8 - Connected to a USB MUX to select between USB2_DP0 (OTG) * and USB2_DP6. 1:OTG, 0:USB */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_9, 1, DEEP, UP_20K), + PAD_CFG_TERM_GPO(GPIO_9, 1, UP_20K, DEEP) /* EN_I2CPM_EXT_1V8 - Connected to OE pin of I2C Re-driver. * Allow/Disallow I2C signal to pass through to SMARC Connector. */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_10, 1, DEEP, UP_20K), + PAD_CFG_TERM_GPO(GPIO_10, 1, UP_20K, DEEP) /* EN_SMB_EXT_1V8 - Connected to OE pin of I2C Re-driver. * Allow/Disallow SMBUS signal to pass through to SMARC Connector. */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_11, 0, DEEP, UP_20K), + PAD_CFG_TERM_GPO(GPIO_11, 0, UP_20K, DEEP) /* BOOT_SEL2_1V8# - Three Module pins allow the Carrier board user to * select from eight possible boot devices. */ @@ -413,13 +413,13 @@ */ PAD_CFG_GPI_INT(GPIO_14, UP_20K, DEEP, OFF), /* GPIO_CPLD_TCK_1V8 */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_15, 0, DEEP, DN_20K), + PAD_CFG_TERM_GPO(GPIO_15, 0, DN_20K, DEEP), /* GPIO_CPLD_TMS_1V8 */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_16, 0, DEEP, DN_20K), + PAD_CFG_TERM_GPO(GPIO_16, 0, DN_20K, DEEP), /* GPIO_CPLD_TDI_1V8 */ PAD_CFG_GPI_INT(GPIO_17, DN_20K, DEEP, OFF), /* GPIO_CPLD_TDO_1V8 */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_18, 0, DEEP, DN_20K), + PAD_CFG_TERM_GPO(GPIO_18, 0, DN_20K, DEEP), /* PM_TEST_1V8# connect to the SMARC Connector TEST# pin. * Held low by Carrier to invoke Module vendor specific test function. * Pulled up on Module. Driven by OD part on Carrier. @@ -464,9 +464,9 @@ /* SMB_ALERT_GPIO# */ PAD_CFG_GPI_INT(GPIO_27, UP_20K, DEEP, OFF), /* GPIO_28_DEBUG - Connect to HOOK5 (ClkOut#) pin of XDP connector */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_28, 1, DEEP, UP_20K), + PAD_CFG_TERM_GPO(GPIO_28, 1, UP_20K, DEEP) /* GPIO_29_DEBUG - Connect to HOOK4 (ClkOut) pin of XDP connector */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_29, 0, DEEP, DN_20K), + PAD_CFG_TERM_GPO(GPIO_29, 0, DN_20K, DEEP), /* Not connected */ PAD_CFG_GPI_INT(GPIO_30, DN_20K, DEEP, OFF), @@ -484,21 +484,21 @@ /* STRAP_GPIO_36 (int. PD) */ PAD_CFG_GPI_INT(GPIO_36, DN_20K, DEEP, OFF), /* Not connected */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_37, 0, DEEP, DN_20K), + PAD_CFG_TERM_GPO(GPIO_37, 0, DN_20K, DEEP), /* GPIO_VALID (CPLD=gpio_valid/pi_gpio_en)- This pin Enable the CPLD * GPIO to the SMARC Connector. */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_62, 1, DEEP, UP_20K), + PAD_CFG_TERM_GPO(GPIO_62, 1, UP_20K, DEEP) /* LVDS_ENABLE_1V8# connect to PTN3460 DP to LVDS converter chip. */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_63, 0, DEEP, DN_20K), + PAD_CFG_TERM_GPO(GPIO_63, 0, DN_20K, DEEP), /* Not connected */ PAD_CFG_GPIO_DRIVER_HI_Z(GPIO_64, DN_20K, DEEP, HIZCRx0, SAME), /* Not connected */ PAD_CFG_GPIO_DRIVER_HI_Z(GPIO_65, DN_20K, DEEP, HIZCRx0, SAME), /* CAM_CS0_CS1_SEL - Serial Cameras interfaces Select - to select * between the two MIPI CSI camera interfaces on the SMARC connector. */ - PAD_CFG_GPO_GPIO_DRIVER(GPIO_66, 0, DEEP, DN_20K), + PAD_CFG_TERM_GPO(GPIO_66, 0, DN_20K, DEEP), /* MCSI0_RST_1V8# - Reset the MIPI CSI camera interfaces 0 */ PAD_CFG_GPO_IOSSTATE_IOSTERM(GPIO_67, 0, DEEP, DN_20K, HIZCRx0, SAME), /* MCSI1_RST_1V8# - Reset the MIPI CSI camera interfaces 1 */ -- To view, visit
https://review.coreboot.org/c/coreboot/+/44469
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I406a08e526a6c655f38e4c0a355957c98e93881c Gerrit-Change-Number: 44469 Gerrit-PatchSet: 1 Gerrit-Owner: Maxim Polyakov <max.senia.poliak(a)gmail.com> Gerrit-Reviewer: Werner Zeh <werner.zeh(a)siemens.com> Gerrit-MessageType: newchange
3
3
0
0
Change in coreboot[master]: vendorcode/intel/fsp/alderlake: Fix FSPS_ARCH_UPD redefinition issue
by Subrata Banik (Code Review)
10 Sep '20
10 Sep '20
Subrata Banik has uploaded this change for review. (
https://review.coreboot.org/c/coreboot/+/45191
) Change subject: vendorcode/intel/fsp/alderlake: Fix FSPS_ARCH_UPD redefinition issue ...................................................................... vendorcode/intel/fsp/alderlake: Fix FSPS_ARCH_UPD redefinition issue FSPS_ARCH_UPD struct is part of edk2-stable202005 branch (FspApi.h) hence local definition of FSPS_ARCH_UPD inside FspsUpd.h is causing compilation issue. Change-Id: Id5b3637d9ab6d87aab6da810f9c83d3258900a29 Signed-off-by: Subrata Banik <subrata.banik(a)intel.com> --- M src/vendorcode/intel/fsp/fsp2_0/alderlake/FspsUpd.h 1 file changed, 0 insertions(+), 30 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/91/45191/1 diff --git a/src/vendorcode/intel/fsp/fsp2_0/alderlake/FspsUpd.h b/src/vendorcode/intel/fsp/fsp2_0/alderlake/FspsUpd.h index 39c360d..7ec577a 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/alderlake/FspsUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/alderlake/FspsUpd.h @@ -80,36 +80,6 @@ #define SI_PCH_MAX_DEVICE_INTERRUPT_CONFIG 64 ///< Number of all PCH devices - -/** FSPS_ARCH_UPD -**/ -typedef struct { - -/** Offset 0x0020 - Reserved -**/ - UINT8 Revision; - -/** Offset 0x0021 - Reserved -**/ - UINT8 Reserved[3]; - -/** Offset 0x0024 - Reserved -**/ - UINT32 Length; - -/** Offset 0x0028 - Reserved -**/ - UINT32 FspEventHandler; - -/** Offset 0x002C - Reserved -**/ - UINT8 EnableMultiPhaseSiliconInit; - -/** Offset 0x002D - Reserved -**/ - UINT8 Reserved1[19]; -} FSPS_ARCH_UPD; - /** Fsp S Configuration **/ typedef struct { -- To view, visit
https://review.coreboot.org/c/coreboot/+/45191
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: Id5b3637d9ab6d87aab6da810f9c83d3258900a29 Gerrit-Change-Number: 45191 Gerrit-PatchSet: 1 Gerrit-Owner: Subrata Banik <subrata.banik(a)intel.com> Gerrit-MessageType: newchange
4
5
0
0
Change in coreboot[master]: soc/intel/alderlake: Rename pch_init() code
by Subrata Banik (Code Review)
10 Sep '20
10 Sep '20
Subrata Banik has uploaded this change for review. (
https://review.coreboot.org/c/coreboot/+/45189
) Change subject: soc/intel/alderlake: Rename pch_init() code ...................................................................... soc/intel/alderlake: Rename pch_init() code Rename the pch_init function to bootblock_pch_init. Change-Id: Id2a89b2f64b58079062d79e07efbdcfad7ed3d2d Signed-off-by: Subrata Banik <subrata.banik(a)intel.com> --- M src/soc/intel/alderlake/bootblock/bootblock.c M src/soc/intel/alderlake/bootblock/pch.c M src/soc/intel/alderlake/include/soc/bootblock.h 3 files changed, 3 insertions(+), 3 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/89/45189/1 diff --git a/src/soc/intel/alderlake/bootblock/bootblock.c b/src/soc/intel/alderlake/bootblock/bootblock.c index e7d97c5..96e6268 100644 --- a/src/soc/intel/alderlake/bootblock/bootblock.c +++ b/src/soc/intel/alderlake/bootblock/bootblock.c @@ -25,7 +25,7 @@ void bootblock_soc_init(void) { report_platform_info(); - pch_init(); + bootblock_pch_init(); /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */ tco_configure(); diff --git a/src/soc/intel/alderlake/bootblock/pch.c b/src/soc/intel/alderlake/bootblock/pch.c index 8452d83..b7d2c15 100644 --- a/src/soc/intel/alderlake/bootblock/pch.c +++ b/src/soc/intel/alderlake/bootblock/pch.c @@ -138,7 +138,7 @@ pch_enable_lpc(); } -void pch_init(void) +void bootblock_pch_init(void) { /* * Enabling ABASE for accessing PM1_STS, PM1_EN, PM1_CNT, diff --git a/src/soc/intel/alderlake/include/soc/bootblock.h b/src/soc/intel/alderlake/include/soc/bootblock.h index 9816b31..087d29f 100644 --- a/src/soc/intel/alderlake/include/soc/bootblock.h +++ b/src/soc/intel/alderlake/include/soc/bootblock.h @@ -8,7 +8,7 @@ void bootblock_pch_early_init(void); /* Bootblock post console init programming */ -void pch_init(void); +void bootblock_pch_init(void); void pch_early_iorange_init(void); void report_platform_info(void); -- To view, visit
https://review.coreboot.org/c/coreboot/+/45189
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: Id2a89b2f64b58079062d79e07efbdcfad7ed3d2d Gerrit-Change-Number: 45189 Gerrit-PatchSet: 1 Gerrit-Owner: Subrata Banik <subrata.banik(a)intel.com> Gerrit-MessageType: newchange
4
6
0
0
Change in coreboot[master]: soc/intel/tigerlake: Maintain consistent tab in iomap.h
by Subrata Banik (Code Review)
10 Sep '20
10 Sep '20
Subrata Banik has uploaded this change for review. (
https://review.coreboot.org/c/coreboot/+/45194
) Change subject: soc/intel/tigerlake: Maintain consistent tab in iomap.h ...................................................................... soc/intel/tigerlake: Maintain consistent tab in iomap.h This patch converts inconsistent white space into tab. Signed-off-by: Subrata Banik <subrata.banik(a)intel.com> Change-Id: If5e191b92e3e53b43335136ef51bc62589b955a0 --- M src/soc/intel/tigerlake/include/soc/iomap.h 1 file changed, 1 insertion(+), 1 deletion(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/94/45194/1 diff --git a/src/soc/intel/tigerlake/include/soc/iomap.h b/src/soc/intel/tigerlake/include/soc/iomap.h index cd964f0..6fa29d3 100644 --- a/src/soc/intel/tigerlake/include/soc/iomap.h +++ b/src/soc/intel/tigerlake/include/soc/iomap.h @@ -53,7 +53,7 @@ #define GFXVT_BASE_ADDRESS 0xfed90000 #define GFXVT_BASE_SIZE 0x1000 -#define IPUVT_BASE_ADDRESS 0xfed92000 +#define IPUVT_BASE_ADDRESS 0xfed92000 #define IPUVT_BASE_SIZE 0x1000 #define VTVC0_BASE_ADDRESS 0xfed91000 -- To view, visit
https://review.coreboot.org/c/coreboot/+/45194
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: If5e191b92e3e53b43335136ef51bc62589b955a0 Gerrit-Change-Number: 45194 Gerrit-PatchSet: 1 Gerrit-Owner: Subrata Banik <subrata.banik(a)intel.com> Gerrit-MessageType: newchange
5
5
0
0
Change in coreboot[master]: sc7180: Add display hardware pipe line initialization [patch 3 of 3]
by Ravi kumar (Code Review)
10 Sep '20
10 Sep '20
Ravi kumar has uploaded this change for review. (
https://review.coreboot.org/c/coreboot/+/39615
) Change subject: sc7180: Add display hardware pipe line initialization [patch 3 of 3] ...................................................................... sc7180: Add display hardware pipe line initialization [patch 3 of 3] Add sc7180 display hardware pipeline programming support and invoke the display initialization from soc_init Change-Id: I7d5e3f1781c48759553243abeb3d694f76cd008e Signed-off-by: Vinod Polimera <vpolimer(a)codeaurora.org> --- M src/soc/qualcomm/sc7180/Kconfig M src/soc/qualcomm/sc7180/Makefile.inc A src/soc/qualcomm/sc7180/display.c A src/soc/qualcomm/sc7180/display/mdss.c A src/soc/qualcomm/sc7180/display/oem_panel.c A src/soc/qualcomm/sc7180/include/soc/display.h A src/soc/qualcomm/sc7180/include/soc/display/panel_sn65dsix6_auo_bll6xak01_dsi_video.h M src/soc/qualcomm/sc7180/soc.c 8 files changed, 1,448 insertions(+), 1 deletion(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/15/39615/1 diff --git a/src/soc/qualcomm/sc7180/Kconfig b/src/soc/qualcomm/sc7180/Kconfig index 5ef5360..b07f518 100644 --- a/src/soc/qualcomm/sc7180/Kconfig +++ b/src/soc/qualcomm/sc7180/Kconfig @@ -14,6 +14,9 @@ select SOC_QUALCOMM_COMMON select HAVE_UART_SPECIAL select BOOTBLOCK_CONSOLE + select MAINBOARD_HAS_NATIVE_VGA_INIT + select MAINBOARD_FORCE_NATIVE_VGA_INIT + select HAVE_LINEAR_FRAMEBUFFER if SOC_QUALCOMM_SC7180 diff --git a/src/soc/qualcomm/sc7180/Makefile.inc b/src/soc/qualcomm/sc7180/Makefile.inc index 7df4f6e..8bdd329 100644 --- a/src/soc/qualcomm/sc7180/Makefile.inc +++ b/src/soc/qualcomm/sc7180/Makefile.inc @@ -59,6 +59,14 @@ ramstage-y += qupv3_config.c ramstage-y += qcom_qup_se.c ramstage-$(CONFIG_DRIVERS_UART) += qupv3_uart.c +ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display/oem_panel.c +ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display/mdss.c +ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display/target_sc7180.c +ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display/dsi_panel_display.c +ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display/dsi_phy_pll.c +ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display/dsi_phy.c +ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display/dsi.c +ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += display.c ################################################################################ diff --git a/src/soc/qualcomm/sc7180/display.c b/src/soc/qualcomm/sc7180/display.c new file mode 100644 index 0000000..1759179 --- /dev/null +++ b/src/soc/qualcomm/sc7180/display.c @@ -0,0 +1,275 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2020 Qualcomm Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + + +#include <stdlib.h> +#include <console/console.h> +#include <delay.h> +#include <device/device.h> +#include <soc/mdss_6_2_0.h> +#include <soc/display/panel.h> +#include <soc/display/mipi_dsi.h> +#include <soc/display/panel_display.h> +#include <soc/display/target_sc7180.h> +#include <soc/display.h> + +static struct msm_fb_panel_data panel; +struct panel_struct panelstruct; +static uint8_t display_enable; +static struct mdss_dsi_phy_ctrl dsi_video_mode_phy_db; +extern int msm_display_init(struct msm_fb_panel_data *pdata); +int msm_display_config(void); + +static int update_dsi_display_config(void) +{ + /* Place holder to handle dual dsi cases in future */ + int ret = NO_ERROR; + return ret; +} + +static uint32_t mdss_dsi_panel_clock(uint8_t enable, + struct msm_panel_info *pinfo) +{ + /* MDSS Clocks are set in QCLib. DSI clocks are set after programming + * DSI Phy and Pll. This will be place holder if we want to enable + * MDSS Clocks in coreboot later. + */ + return NO_ERROR; +} + +static uint32_t mdss_dsi_panel_reset(uint8_t enable) +{ + uint32_t ret = NO_ERROR; +// if (panelstruct.panelresetseq) //TODO: check if bridge reset seq? + ret = target_panel_reset(enable, panelstruct.panelresetseq, + &panel.panel_info); + return ret; +} + +static int mdss_dsi_panel_power(uint8_t enable, + struct msm_panel_info *pinfo) +{ + int ret = NO_ERROR; + if (enable) { + ret = mdss_dsi_panel_reset(enable); + if (ret) { + printk(BIOS_ERR, "panel reset failed\n"); + return ret; + } + } else { + ret = mdss_dsi_panel_reset(enable); + if (ret) { + printk(BIOS_ERR, "panel reset disable failed\n"); + return ret; + } + } + + return ret; +} + +static int mdss_dsi_panel_pre_init(void) +{ + int ret = NO_ERROR; + if (panelstruct.paneldata->panel_lp11_init) { + ret = mdss_dsi_panel_reset(1); + if (ret) { + printk(BIOS_ERR, "panel reset failed\n"); + return ret; + } + } + if (panelstruct.paneldata->panel_init_delay) + udelay(panelstruct.paneldata->panel_init_delay); + + printk(BIOS_INFO, "Panel pre init done\n"); + return ret; +} + +static int mdss_dsi_bl_enable(uint8_t enable) +{ + int ret = NO_ERROR; + + ret = target_backlight_ctrl(enable); + if (ret) + printk(BIOS_ERR, "Backlight %s failed\n", enable ? "enable" : + "disable"); + return ret; +} + +int msm_display_config(void) +{ + int ret = NO_ERROR; + struct msm_panel_info *pinfo; + pinfo = &(panel.panel_info); + + mdp_set_revision(panel.mdp_rev); + + switch (pinfo->type) { + case MIPI_VIDEO_PANEL: + printk(BIOS_INFO, "Config MIPI_VIDEO_PANEL.\n"); + ret = mdss_dsi_config(&panel); + if (ret) + goto msm_display_config_out; + + if (pinfo->early_config) + ret = pinfo->early_config((void *)pinfo); + + ret = mdp_dsi_video_config(pinfo, &(panel.fb)); + + if (ret) + goto msm_display_config_out; + + break; + default: + return ERROR; + } + if (pinfo->config) + ret = pinfo->config((void *)pinfo); + +msm_display_config_out: + return ret; +} + +int msm_display_init(struct msm_fb_panel_data *pdata) +{ + int ret = NO_ERROR; + + printk(BIOS_INFO, "%s: Display Initialization start\n", __func__); + if (!pdata) { + ret = ERROR; + goto msm_display_init_out; + } + /* Turn on panel */ + if (pdata->power_func) + ret = pdata->power_func(1, &(pdata->panel_info)); + + if (ret) + goto msm_display_init_out; + + /* Enable clock */ + if (pdata->clk_func) + ret = pdata->clk_func(1, &(pdata->panel_info)); + if (ret) + goto msm_display_init_out; + + if (pdata->update_panel_info) + ret = pdata->update_panel_info(); + + if (ret) + goto msm_display_init_out; + + if (pdata->pll_clk_func) + ret = pdata->pll_clk_func(1, &(pdata->panel_info)); + if (ret) + goto msm_display_init_out; + + /* pinfo prepare */ + if (pdata->panel_info.prepare) { + /* this is for edp which pinfo derived from edid */ + ret = pdata->panel_info.prepare(); + pdata->fb.width = pdata->panel_info.xres; + pdata->fb.height = pdata->panel_info.yres; + pdata->fb.stride = pdata->panel_info.xres; + pdata->fb.bpp = pdata->panel_info.bpp; + } + + if (ret) + goto msm_display_init_out; + + ret = msm_display_config(); + + if (ret) + goto msm_display_init_out; + + ret = mdp_dsi_video_on(&(pdata->panel_info)); + + if (ret) + goto msm_display_init_out; + + if (pdata->post_power_func) + ret = pdata->post_power_func(1); + + if (ret) + goto msm_display_init_out; + + /* Turn on backlight */ + if (pdata->bl_func) + ret = pdata->bl_func(1); + if (ret) + goto msm_display_init_out; + +msm_display_init_out: + return ret; +} + +/* This has to be called from soc init, with right MDP rev */ +int display_init(const char *panel_name, uint32_t rev, struct edid *ed) +{ + int ret = NO_ERROR; + int pan_type; + dsi_video_mode_phy_db.pll_type = DSI_PLL_TYPE_10NM; + printk(BIOS_INFO, " display init!\n"); + pan_type = oem_panel_select(panel_name, &panelstruct, + &(panel.panel_info), + &dsi_video_mode_phy_db); + if (pan_type == PANEL_TYPE_DSI) { + if (update_dsi_display_config()) + goto error_display_init; + target_dsi_phy_config(&dsi_video_mode_phy_db); + if (dsi_panel_init(&(panel.panel_info), &panelstruct)) { + printk(BIOS_ERR, "DSI panel init failed!\n"); + ret = ERROR; + goto error_display_init; + } + panel.panel_info.mipi.mdss_dsi_phy_db = &dsi_video_mode_phy_db; + panel.pll_clk_func = mdss_dsi_panel_clock; + panel.power_func = mdss_dsi_panel_power; + panel.pre_init_func = mdss_dsi_panel_pre_init; + panel.bl_func = mdss_dsi_bl_enable; + + panel.fb.base = NULL; /* Filled in DC */ + panel.fb.width = panel.panel_info.xres; + panel.fb.height = panel.panel_info.yres; + panel.fb.stride = panel.panel_info.xres; + panel.fb.bpp = panel.panel_info.bpp; + panel.fb.format = panel.panel_info.mipi.dst_format; + panel.fb.sbpp = FRAMEBUFFER_SRC_BPP; + if (ed != NULL) { + ed->mode.ha = panel.panel_info.xres; + ed->mode.va = panel.panel_info.yres; + ed->framebuffer_bits_per_pixel = FRAMEBUFFER_SRC_BPP; + } + } else { + printk(BIOS_ERR, "Target panel init not found!\n"); + ret = ERROR; + goto error_display_init; + } + panel.mdp_rev = rev; + ret = msm_display_init(&panel); + +error_display_init: + display_enable = ret ? 0 : 1; + return ret; +} + +void sc7180_display_init(struct device *dev) +{ + /* Restricting display hw initialization to cheza boards only */ + static struct edid ed; + printk(BIOS_INFO, "sc7180 display init!\n"); + display_init(NULL, MDSS_MDP_HW_REV_620, &ed); + edid_set_framebuffer_bits_per_pixel(&ed, ed.framebuffer_bits_per_pixel, + 0); + set_vbe_mode_info_valid(&ed, (uintptr_t)0); +} diff --git a/src/soc/qualcomm/sc7180/display/mdss.c b/src/soc/qualcomm/sc7180/display/mdss.c new file mode 100644 index 0000000..f949729 --- /dev/null +++ b/src/soc/qualcomm/sc7180/display/mdss.c @@ -0,0 +1,679 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2020 Qualcomm Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include <arch/mmio.h> +#include <stdlib.h> +#include <console/console.h> +#include <delay.h> +#include <soc/mdss_6_2_0.h> +#include <soc/display/target_sc7180.h> +#include <soc/display/msm_panel.h> +#include <soc/display/mipi_dsi.h> + +#define MDSS_MDP_MAX_PREFILL_FETCH 25 + +uint32_t mdss_mdp_intf_offset(void); + +void mdss_layer_mixer_setup(struct fbcon_config *fb, struct msm_panel_info + *pinfo); + +void mdss_vbif_qos_remapper_setup(struct msm_panel_info *pinfo); + +int mdp_dsi_video_off(struct msm_panel_info *pinfo); + +int mdp_dsi_cmd_off(void); + +static int mdp_rev; + +void mdp_set_revision(int rev) +{ + mdp_rev = rev; +} + +int mdp_get_revision(void) +{ + return mdp_rev; +} + +uint32_t mdss_mdp_intf_offset(void) +{ + return 0; +} + +static uint32_t mdss_mdp_get_ppb_offset(void) +{ + uint32_t mdss_mdp_ppb_off = 0; + uint32_t mdss_mdp_rev = readl(MDP_HW_REV); + + /* return MMSS_MDP_PPB0_CONFIG offset from MDSS base */ + if (mdss_mdp_rev == MDSS_MDP_HW_REV_620) + mdss_mdp_ppb_off = 0x1420; //TODO: check if it is required atall + else + printk(BIOS_ERR, "Invalid PPB0_CONFIG offset\n"); + + return mdss_mdp_ppb_off; +} + +static void mdp_select_pipe_type(struct msm_panel_info *pinfo, + uint32_t *left_pipe, uint32_t *right_pipe) +{ + switch (pinfo->pipe_type) { + + case MDSS_MDP_PIPE_TYPE_DMA: + *left_pipe = MDP_VP_0_DMA_0_BASE; + *right_pipe = MDP_VP_0_DMA_1_BASE; + break; + + case MDSS_MDP_PIPE_TYPE_VIG: + default: + *left_pipe = MDP_VP_0_VIG_0_BASE; + *right_pipe = MDP_VP_0_VIG_1_BASE; + break; + } +} + +static void mdss_mdp_set_flush(struct msm_panel_info *pinfo, + uint32_t *ctl0_reg_val, uint32_t *ctl1_reg_val) +{ + bool dual_pipe_single_ctl = pinfo->lcdc.dual_pipe && + !pinfo->mipi.dual_dsi && + !pinfo->lcdc.split_display; + + *ctl0_reg_val = BIT(17); /*attach ctl path */ + *ctl1_reg_val = BIT(17); + + switch (pinfo->pipe_type) { + + case MDSS_MDP_PIPE_TYPE_DMA: + if (dual_pipe_single_ctl) + *ctl0_reg_val |= BIT(12)| BIT(11) | BIT(6) | BIT(7); + else + *ctl0_reg_val |= BIT(12) | BIT(11) | BIT(6); + + *ctl1_reg_val |= BIT(12)| BIT(7); + + if (pinfo->lcdc.dst_split) + *ctl0_reg_val |= BIT(12); + break; + + case MDSS_MDP_PIPE_TYPE_VIG: + default: + if (dual_pipe_single_ctl) + *ctl0_reg_val |= BIT(0)| BIT(1) |BIT(6) | BIT(7); + else + *ctl0_reg_val |= BIT(0)| BIT(6); + + *ctl1_reg_val |= BIT(7)|BIT(1); + + if (pinfo->lcdc.dst_split) + *ctl0_reg_val |= BIT(1); + + break; + } + + *ctl0_reg_val |= BIT(31); /*Interface flush */ + *ctl1_reg_val |= BIT(31); +} + +static void mdss_source_pipe_config(struct fbcon_config *fb, + struct msm_panel_info *pinfo, + uint32_t pipe_base) +{ + uint32_t img_size, out_size, stride; + uint32_t fb_off = 0; + uint32_t flip_bits = 0; + uint32_t src_xy = 0; + uint32_t dst_xy = 0; + uint32_t height, width; + + height = fb->height - pinfo->border_top - pinfo->border_bottom; + width = fb->width - pinfo->border_left - pinfo->border_right; + + /* write active region size*/ + img_size = (height << 16) | width; + out_size = img_size; + + if (pinfo->lcdc.dual_pipe) { + + if ((pipe_base == MDP_VP_0_DMA_1_BASE) || + (pipe_base == MDP_VP_0_VIG_1_BASE)) { + fb_off = (pinfo->xres / 2); + out_size = (height << 16) + (pinfo->lm_split[1]); + } + else { + out_size = (height << 16) + (pinfo->lm_split[0]); + } + } + + stride = (fb->stride * fb->sbpp/8); + + if (fb_off == 0) { /* left */ + dst_xy = (pinfo->border_top << 16) | pinfo->border_left; + src_xy = dst_xy; + } else { /* right */ + dst_xy = (pinfo->border_top << 16); + src_xy = (pinfo->border_top << 16) | fb_off; + } + + printk(BIOS_INFO, "%s: src=%x fb_off=%x src_xy=%x dst_xy=%x\n", + __func__, out_size, fb_off, src_xy, dst_xy); + + writel(stride, pipe_base + PIPE_SSPP_SRC_YSTRIDE); + + writel(out_size, pipe_base + PIPE_SSPP_SRC_SIZE); + writel(out_size, pipe_base + PIPE_SSPP_SRC_OUT_SIZE); + writel(src_xy, pipe_base + PIPE_SSPP_SRC_XY); + writel(dst_xy, pipe_base + PIPE_SSPP_OUT_XY); + + /* Tight Packing 4bpp Alpha 8-bit A R B G */ + writel(0x000236ff, pipe_base + PIPE_SSPP_SRC_FORMAT); + writel(0x03020001, pipe_base + PIPE_SSPP_SRC_UNPACK_PATTERN); + + /* bit(0) is set if hflip is required. + * bit(1) is set if vflip is required. + */ + if (pinfo->orientation & 0x1) + flip_bits |= MDSS_MDP_OP_MODE_FLIP_LR; + if (pinfo->orientation & 0x2) + flip_bits |= MDSS_MDP_OP_MODE_FLIP_UD; + + flip_bits |= BIT(31); + writel(out_size, pipe_base + PIPE_SW_PIXEL_EXT_C0_REQ); + writel(out_size, pipe_base + PIPE_SW_PIXEL_EXT_C1C2_REQ); + writel(out_size, pipe_base + PIPE_SW_PIXEL_EXT_C3_REQ); + writel(flip_bits, pipe_base + PIPE_SSPP_SRC_OP_MODE); + +} + +static void mdss_vbif_setup(void) +{ + writel(0x33333333, VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0); + writel(0x00333333, VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1); +} + +static void mdss_intf_tg_setup(struct msm_panel_info *pinfo, uint32_t intf_base) +{ + uint32_t hsync_period, vsync_period; + uint32_t hsync_start_x, hsync_end_x; + uint32_t display_hctl, hsync_ctl, display_vstart, display_vend; + uint32_t adjust_xres = 0; + uint32_t upper = 0, lower = 0; + + struct lcdc_panel_info *lcdc = NULL; + struct intf_timing_params itp = {0}; + + if (pinfo == NULL) + return; + + lcdc = &(pinfo->lcdc); + if (lcdc == NULL) + return; + + adjust_xres = pinfo->xres; + if (pinfo->lcdc.split_display) { + if (pinfo->lcdc.dst_split) { + adjust_xres /= 2; + } else if (pinfo->lcdc.dual_pipe) { + if (intf_base == + (MDP_INTF_1_BASE + mdss_mdp_intf_offset())) + adjust_xres = pinfo->lm_split[0]; + else + adjust_xres = pinfo->lm_split[1]; + } + + if (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset())) { + if (pinfo->lcdc.pipe_swap) { + lower |= BIT(4); + upper |= BIT(8); + } else { + lower |= BIT(8); + upper |= BIT(4); + } + writel(lower, MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL); + writel(upper, MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL); + writel(0x1, MDP_REG_SPLIT_DISPLAY_EN); + } + } + + if (pinfo->lcdc.dst_split && + (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset()))) { + uint32_t ppb_offset = mdss_mdp_get_ppb_offset(); + + writel(BIT(5), REG_MDP(ppb_offset)); /* MMSS_MDP_PPB0_CNTL */ + writel(BIT(16) | (0x3 << 20), REG_MDP(ppb_offset + 0x4)); + } + + itp.xres = adjust_xres; + itp.yres = pinfo->yres; + itp.width = (adjust_xres + pinfo->lcdc.xres_pad); + + if (pinfo->compression_mode == COMPRESSION_DSC) { + itp.xres = pinfo->dsc.pclk_per_line; + itp.width = pinfo->dsc.pclk_per_line; + } + + itp.height = pinfo->yres + pinfo->lcdc.yres_pad; + itp.h_back_porch = pinfo->lcdc.h_back_porch; + itp.h_front_porch = pinfo->lcdc.h_front_porch; + itp.v_back_porch = pinfo->lcdc.v_back_porch; + itp.v_front_porch = pinfo->lcdc.v_front_porch; + itp.hsync_pulse_width = pinfo->lcdc.h_pulse_width; + itp.vsync_pulse_width = pinfo->lcdc.v_pulse_width; + + itp.border_clr = pinfo->lcdc.border_clr; + itp.underflow_clr = pinfo->lcdc.underflow_clr; + itp.hsync_skew = pinfo->lcdc.hsync_skew; + + hsync_period = itp.hsync_pulse_width + itp.h_back_porch + + itp.width + itp.h_front_porch; + + vsync_period = itp.vsync_pulse_width + itp.v_back_porch + + itp.height + itp.v_front_porch; + + hsync_start_x = itp.hsync_pulse_width + + itp.h_back_porch; + hsync_end_x = hsync_period - itp.h_front_porch - 1; + + display_vstart = (itp.vsync_pulse_width + + itp.v_back_porch) * + hsync_period + itp.hsync_skew; + + display_vend = ((vsync_period - itp.v_front_porch) * hsync_period) + + itp.hsync_skew - 1; + + if (intf_base == (MDP_INTF_0_BASE + mdss_mdp_intf_offset())) { /* eDP */ + display_vstart += itp.hsync_pulse_width + itp.h_back_porch; + display_vend -= itp.h_front_porch; + } + + hsync_ctl = (hsync_period << 16) | itp.hsync_pulse_width; + display_hctl = (hsync_end_x << 16) | hsync_start_x; + + writel(hsync_ctl, MDP_HSYNC_CTL + intf_base); + writel(vsync_period*hsync_period, MDP_VSYNC_PERIOD_F0 + + intf_base); + writel(itp.vsync_pulse_width*hsync_period, + MDP_VSYNC_PULSE_WIDTH_F0 + + intf_base); + writel(display_hctl, MDP_DISPLAY_HCTL + intf_base); + writel(display_vstart, MDP_DISPLAY_V_START_F0 + + intf_base); + writel(display_vend, MDP_DISPLAY_V_END_F0 + + intf_base); + writel(itp.underflow_clr, MDP_UNDERFFLOW_COLOR + intf_base); + writel(0x2100, MDP_PANEL_FORMAT + intf_base); +} + +static void mdss_intf_fetch_start_config(struct msm_panel_info *pinfo, + uint32_t intf_base) +{ + uint32_t v_total, h_total, fetch_start, vfp_start; + uint32_t prefetch_avail, prefetch_needed; + uint32_t adjust_xres = 0; + uint32_t fetch_enable = BIT(31); + + struct lcdc_panel_info *lcdc = NULL; + + if (pinfo == NULL) + return; + + lcdc = &(pinfo->lcdc); + if (lcdc == NULL) + return; + + /* + * MDP programmable fetch is for MDP with rev >= 1.05. + * Programmable fetch is not needed if vertical back porch + * plus vertical puls width is >= 25. + */ + if ((lcdc->v_back_porch + lcdc->v_pulse_width) >= MDSS_MDP_MAX_PREFILL_FETCH) + return; + + adjust_xres = pinfo->xres; + if (pinfo->lcdc.split_display) { + if (pinfo->lcdc.dst_split) { + adjust_xres /= 2; + } else if (pinfo->lcdc.dual_pipe) { + if (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset())) + adjust_xres = pinfo->lm_split[0]; + else + adjust_xres = pinfo->lm_split[1]; + } + } + + if (pinfo->compression_mode == COMPRESSION_DSC) + adjust_xres = pinfo->dsc.pclk_per_line; + + /* + * Fetch should always be outside the active lines. If the fetching + * is programmed within active region, hardware behavior is unknown. + */ + v_total = lcdc->v_pulse_width + lcdc->v_back_porch + pinfo->yres + + lcdc->v_front_porch; + h_total = lcdc->h_pulse_width + lcdc->h_back_porch + adjust_xres + + lcdc->h_front_porch; + vfp_start = lcdc->v_pulse_width + lcdc->v_back_porch + pinfo->yres; + + prefetch_avail = v_total - vfp_start; + prefetch_needed = MDSS_MDP_MAX_PREFILL_FETCH - lcdc->v_back_porch - + lcdc->v_pulse_width; + + /* + * In some cases, vertical front porch is too high. In such cases limit + * the mdp fetch lines as the last (25 - vbp - vpw) lines of + * vertical front porch. + */ + if (prefetch_avail > prefetch_needed) + prefetch_avail = prefetch_needed; + + fetch_start = (v_total - prefetch_avail) * h_total+ h_total + 1; + + if (pinfo->dfps.panel_dfps.enabled) + fetch_enable |= BIT(23); //TODO: this shoudld not be enabled ? + + writel(fetch_start, MDP_PROG_FETCH_START + intf_base); + + writel(fetch_enable, MDP_INTF_CONFIG + intf_base); + +} + +void mdss_layer_mixer_setup(struct fbcon_config *fb, struct msm_panel_info + *pinfo) +{ + uint32_t mdp_rgb_size, height, width; + uint32_t left_staging_level, right_staging_level; + + height = fb->height; + width = fb->width; + + if (pinfo->lcdc.dual_pipe && !pinfo->lcdc.dst_split) + width = pinfo->lm_split[0]; + + /* write active region size*/ + mdp_rgb_size = (height << 16) | width; + + writel(mdp_rgb_size, MDP_VP_0_MIXER_0_BASE + LAYER_0_OUT_SIZE); + writel(0x00, MDP_VP_0_MIXER_0_BASE + LAYER_0_OP_MODE); + + for (int i = 0; i < 6; i++) { + writel(0x100, MDP_VP_0_MIXER_0_BASE + LAYER_0_BLEND_OP(i)); + writel(0x00ff0000, MDP_VP_0_MIXER_0_BASE + LAYER_0_BLEND0_CONST_ALPHA(i)); + } + + left_staging_level =BIT(24); //attach border + right_staging_level=BIT(24); + + switch (pinfo->pipe_type) { + case MDSS_MDP_PIPE_TYPE_DMA: + left_staging_level |= BIT(18); + right_staging_level |= BIT(21); + break; + case MDSS_MDP_PIPE_TYPE_VIG: + default: + left_staging_level |= BIT(1); + right_staging_level |= BIT(3); + break; + } + + /* + * When ping-pong split is enabled and two pipes are used, + * both the pipes need to be staged on the same layer mixer. + */ + if (pinfo->lcdc.dual_pipe && pinfo->lcdc.dst_split) + left_staging_level |= right_staging_level; + + /* Base layer for layer mixer 0 */ + writel(left_staging_level, MDP_CTL_0_BASE + CTL_LAYER_0); + + if (pinfo->lcdc.dual_pipe && !pinfo->lcdc.dst_split) { + /* write active region size*/ + mdp_rgb_size = (height << 16) | pinfo->lm_split[1]; + + writel(mdp_rgb_size, MDP_VP_0_MIXER_1_BASE + LAYER_0_OUT_SIZE); + writel(0x00, MDP_VP_0_MIXER_1_BASE + LAYER_0_OP_MODE); + + for (int i = 0; i < 6; i++) { + writel(0x100, MDP_VP_0_MIXER_1_BASE + LAYER_0_BLEND_OP(i)); + writel(0x00ff0000, MDP_VP_0_MIXER_1_BASE + LAYER_0_BLEND0_CONST_ALPHA(i)); + } + + /* Base layer for layer mixer 1 */ + if (pinfo->lcdc.split_display) + writel(right_staging_level, MDP_CTL_1_BASE + CTL_LAYER_1); + else + writel(right_staging_level, MDP_CTL_0_BASE + CTL_LAYER_1); + } +} + +void mdss_vbif_qos_remapper_setup(struct msm_panel_info *pinfo) +{ + writel(0x00000003, MDSS_VBIF_RT_BASE + 0x550); + writel(0x11111113, MDSS_VBIF_RT_BASE + 0x558); + writel(0x22222224, MDSS_VBIF_RT_BASE + 0x560); + writel(0x33333334, MDSS_VBIF_RT_BASE + 0x568); + writel(0x44444445, MDSS_VBIF_RT_BASE + 0x570); + writel(0x77777776, MDSS_VBIF_RT_BASE + 0x588); + writel(0x00000003, MDSS_VBIF_RT_BASE + 0x590); + writel(0x11111113, MDSS_VBIF_RT_BASE + 0x598); + writel(0x22222224, MDSS_VBIF_RT_BASE + 0x5a0); + writel(0x33333334, MDSS_VBIF_RT_BASE + 0x5a8); + writel(0x44444445, MDSS_VBIF_RT_BASE + 0x5b0); + writel(0x77777776, MDSS_VBIF_RT_BASE + 0x5c8); + +} + +static uint32_t mdss_mdp_ctl_out_sel(struct msm_panel_info *pinfo, + int is_main_ctl) +{ + uint32_t mctl_intf_sel; + uint32_t sctl_intf_sel; + + if ((pinfo->dest == DISPLAY_2) || + ((pinfo->dest == DISPLAY_1) && (pinfo->lcdc.pipe_swap))) { + mctl_intf_sel = BIT(4) | BIT(5); /* Interface 2 */ + sctl_intf_sel = BIT(5); /* Interface 1 */ + } else { + mctl_intf_sel = BIT(5); /* Interface 1 */ + sctl_intf_sel = BIT(4) | BIT(5); /* Interface 2 */ + } + printk(BIOS_INFO, "%s: main ctl dest=%s sec ctl dest=%s\n", __func__, + (mctl_intf_sel & BIT(4)) ? "Intf2" : "Intf1", + (sctl_intf_sel & BIT(4)) ? "Intf2" : "Intf1"); + return is_main_ctl ? mctl_intf_sel : sctl_intf_sel; +} + +static void mdp_set_intf_base(struct msm_panel_info *pinfo, + uint32_t *intf_base, uint32_t *sintf_base) +{ + if (pinfo->dest == DISPLAY_2) { + *intf_base = MDP_INTF_2_BASE; + *sintf_base = MDP_INTF_1_BASE; + } else { + *intf_base = MDP_INTF_1_BASE; + *sintf_base = MDP_INTF_2_BASE; + } +} + +int mdp_dsi_video_config(struct msm_panel_info *pinfo, + struct fbcon_config *fb) +{ + uint32_t intf_sel, sintf_sel; + uint32_t intf_base, sintf_base; + uint32_t left_pipe, right_pipe; + uint32_t reg; + + mdp_set_intf_base(pinfo, &intf_base, &sintf_base); + + mdss_intf_tg_setup(pinfo, intf_base); + mdss_intf_fetch_start_config(pinfo, intf_base); + + if (pinfo->mipi.dual_dsi) { + mdss_intf_tg_setup(pinfo, sintf_base); + mdss_intf_fetch_start_config(pinfo, sintf_base); + } + + mdp_select_pipe_type(pinfo, &left_pipe, &right_pipe); + mdss_vbif_setup(); + mdss_vbif_qos_remapper_setup(pinfo); + + mdss_source_pipe_config(fb, pinfo, left_pipe); + + if (pinfo->lcdc.dual_pipe) + mdss_source_pipe_config(fb, pinfo, right_pipe); + + mdss_layer_mixer_setup(fb, pinfo); + reg = mdss_mdp_ctl_out_sel(pinfo, 1); /*Selecting interface 1 */ + + /* enable 3D mux for dual_pipe but single interface config */ + if (pinfo->lcdc.dual_pipe && !pinfo->mipi.dual_dsi && + !pinfo->lcdc.split_display) { + + if (pinfo->num_dsc_enc != 2) + reg |= BIT(19) | BIT(20); + } + + writel(0x0F0000, MDP_INTF_1_BASE + INTF_MUX); + writel(0x0, MDP_CTL_0_BASE + CTL_TOP); + writel(BIT(1), MDP_CTL_0_BASE + CTL_INTF_ACTIVE); /*Selecting interface 1 */ + + if ((pinfo->compression_mode == COMPRESSION_DSC) && + pinfo->dsc.mdp_dsc_config) { + struct dsc_desc *dsc = &pinfo->dsc; + + if (pinfo->lcdc.dual_pipe && !pinfo->mipi.dual_dsi && + !pinfo->lcdc.split_display && (pinfo->num_dsc_enc == 2)) { + dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE, + MDP_DSC_0_BASE, true, true); + + dsc->mdp_dsc_config(pinfo, MDP_PP_1_BASE, + MDP_DSC_1_BASE, true, true); + + } else if (pinfo->lcdc.dual_pipe && pinfo->mipi.dual_dsi && + pinfo->lcdc.split_display && (pinfo->num_dsc_enc == 1)) { + dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE, + MDP_DSC_0_BASE, false, false); + dsc->mdp_dsc_config(pinfo, MDP_PP_1_BASE, + MDP_DSC_1_BASE, false, false); + + } else { + dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE, + MDP_DSC_0_BASE, false, false); + } + } + + /* + * if dst_split is enabled, intf 1 & 2 needs to be enabled but + * CTL_1 path should not be set since CTL_0 itself is going + * to split after DSPP block and drive both intf. + */ + if (pinfo->mipi.dual_dsi) { + if (!pinfo->lcdc.dst_split) { + reg = 0x1f00 | mdss_mdp_ctl_out_sel(pinfo, 0); + writel(reg, MDP_CTL_1_BASE + CTL_TOP); + } + + intf_sel |= sintf_sel; /* INTF 2 enable */ + } + + return 0; +} + +int mdp_dsi_cmd_config(struct msm_panel_info *pinfo, + struct fbcon_config *fb) +{ + int ret = NO_ERROR; + return ret; +} + +int mdp_dsi_video_on(struct msm_panel_info *pinfo) +{ + uint32_t ctl0_reg_val, ctl1_reg_val; + + writel(0x2, MDP_CTL_0_BASE + CTL_INTF_FLUSH); + mdss_mdp_set_flush(pinfo, &ctl0_reg_val, &ctl1_reg_val); + writel(ctl0_reg_val, MDP_CTL_0_BASE + CTL_FLUSH); + + if (pinfo->lcdc.dual_pipe && !pinfo->lcdc.dst_split){ + writel(0x4, MDP_CTL_1_BASE + CTL_INTF_FLUSH); + writel(ctl1_reg_val, MDP_CTL_1_BASE + CTL_FLUSH); + } + + return NO_ERROR; +} + +static void mdp_set_cmd_autorefresh_mode(struct msm_panel_info *pinfo) +{ + uint32_t total_lines = 0, vclks_line = 0, cfg = 0; + + if (!pinfo || (pinfo->type != MIPI_CMD_PANEL) || !pinfo->autorefresh_enable) + return; + + total_lines = pinfo->lcdc.v_front_porch + + pinfo->lcdc.v_back_porch + + pinfo->lcdc.v_pulse_width + + pinfo->border_top + pinfo->border_bottom + + pinfo->yres; + + total_lines *= pinfo->mipi.frame_rate; + + vclks_line = (total_lines) ? 19200000 / total_lines : 0; + vclks_line = vclks_line * pinfo->mipi.frame_rate * 100 / 6000; + + cfg = BIT(19) | vclks_line; + + /* Configure tearcheck VSYNC param */ + writel(cfg, MDP_REG_PP_0_SYNC_CONFIG_VSYNC); + + if (pinfo->lcdc.dst_split) + writel(cfg, MDP_REG_PP_SLAVE_SYNC_CONFIG_VSYNC); + + if (pinfo->lcdc.dual_pipe) + writel(cfg, MDP_REG_PP_1_SYNC_CONFIG_VSYNC); + dsb(); + + /* Enable autorefresh mode */ + writel((BIT(31) | pinfo->autorefresh_framenum), + MDP_REG_PP_0_AUTOREFRESH_CONFIG); + + if (pinfo->lcdc.dst_split) + writel((BIT(31) | pinfo->autorefresh_framenum), + MDP_REG_PP_SLAVE_AUTOREFRESH_CONFIG); + + if (pinfo->lcdc.dual_pipe) + writel((BIT(31) | pinfo->autorefresh_framenum), + MDP_REG_PP_1_AUTOREFRESH_CONFIG); + + dsb(); +} + +int mdp_dma_on(struct msm_panel_info *pinfo) +{ + uint32_t ctl0_reg_val, ctl1_reg_val; + + mdss_mdp_set_flush(pinfo, &ctl0_reg_val, &ctl1_reg_val); + + writel(ctl0_reg_val, MDP_CTL_0_BASE + CTL_FLUSH); + + if (pinfo->lcdc.dual_pipe && !pinfo->lcdc.dst_split) + writel(ctl1_reg_val, MDP_CTL_1_BASE + CTL_FLUSH); + + if (pinfo->autorefresh_enable) + mdp_set_cmd_autorefresh_mode(pinfo); + + writel(0x01, MDP_CTL_0_BASE + CTL_START); + + return NO_ERROR; +} + diff --git a/src/soc/qualcomm/sc7180/display/oem_panel.c b/src/soc/qualcomm/sc7180/display/oem_panel.c new file mode 100644 index 0000000..da90398 --- /dev/null +++ b/src/soc/qualcomm/sc7180/display/oem_panel.c @@ -0,0 +1,172 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2020 Qualcomm Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include <string.h> +#include <arch/mmio.h> +#include <lib.h> +#include <stdlib.h> +#include <console/console.h> +#include <delay.h> +#include <soc/display/msm_panel.h> +#include <soc/display/mipi_dsi.h> +#include <soc/display/target_sc7180.h> +#include <soc/display/panel_display.h> +#include <soc/mdss_6_2_0.h> +#include <soc/display/panel_sn65dsix6_auo_bll6xak01_dsi_video.h> + +enum { + HW_PLATFORM_MTP, + HW_PLATFORM_PROTO, +}; + +enum { + SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_PANEL, + UNKNOWN_PANEL +}; + +/* + * The list of panels that are supported on this target. + */ +static struct panel_list supp_panels[] = { + {"sn65dsix6_auo_b116xak01_dsi_video", + SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_PANEL}, +}; + +static uint32_t panel_id; +#define SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_PANEL_DELAY 40 + +int oem_panel_bridge_chip_init(struct msm_panel_info *pinfo); + +int oem_panel_rotation(void) +{ + return NO_ERROR; +} + +int oem_panel_on(void) +{ + if (panel_id == SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_PANEL) { + /* needs extra delay to avoid unexpected artifacts */ + mdelay(SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_PANEL_DELAY); + } + + return NO_ERROR; +} + +int oem_panel_off(void) +{ + return NO_ERROR; +} + +static int init_panel_data(struct panel_struct *panelstruct, + struct msm_panel_info *pinfo, + struct mdss_dsi_phy_ctrl *phy_db) +{ + int pan_type = PANEL_TYPE_DSI; + + switch (panel_id) { + case SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_PANEL: + pan_type = PANEL_TYPE_DSI; + panelstruct->paneldata + = &sn65dsix6_auo_b116xak01_dsi_video_panel_data; + panelstruct->paneldata->panel_with_enable_gpio = 0; + panelstruct->panelres + = &sn65dsix6_auo_b116xak01_dsi_video_panel_res; + panelstruct->color + = &sn65dsix6_auo_b116xak01_dsi_video_color; + panelstruct->videopanel + = &sn65dsix6_auo_b116xak01_dsi_video_panel; + panelstruct->commandpanel + = &sn65dsix6_auo_b116xak01_dsi_video_command_panel; + panelstruct->state + = &sn65dsix6_auo_b116xak01_dsi_video_state; + panelstruct->laneconfig + = &sn65dsix6_auo_b116xak01_dsi_video_lane_config; + panelstruct->paneltiminginfo + = &sn65dsix6_auo_b116xak01_dsi_video_timing_info; + panelstruct->panelresetseq + = &sn65dsix6_auo_b116xak01_dsi_video_panel_reset_seq; + pinfo->mipi.panel_on_cmds + = sn65dsix6_auo_b116xak01_dsi_video_on_command; + pinfo->mipi.num_of_panel_on_cmds + = SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_ON_COMMAND; + pinfo->mipi.panel_off_cmds + = sn65dsix6_auo_b116xak01_dsi_video_off_command; + pinfo->mipi.num_of_panel_off_cmds + = SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_OFF_COMMAND; + memcpy(phy_db->timing, + sn65dsix6_auo_b116xak01_dsi_video_timings, + MAX_TIMING_CONFIG * sizeof(uint32_t)); + break; + default: + case UNKNOWN_PANEL: + pan_type = PANEL_TYPE_UNKNOWN; + break; + } + + return pan_type; +} + +int oem_panel_bridge_chip_init(struct msm_panel_info *pinfo) +{ + return target_set_switch_gpio(1); +} + +int oem_panel_select(const char *panel_name, struct panel_struct *panelstruct, + struct msm_panel_info *pinfo, + struct mdss_dsi_phy_ctrl *phy_db) +{ + uint32_t hw_id = HW_PLATFORM_PROTO; + int32_t panel_override_id; + uint32_t ret = 0; + + phy_db->pll_type = DSI_PLL_TYPE_10NM; + + if (panel_name) { + panel_override_id = panel_name_to_id(supp_panels, + ARRAY_SIZE(supp_panels), panel_name); + + if (panel_override_id < 0) { + printk(BIOS_ERR, "Not able to search the panel:%s\n", + panel_name); + } else if (panel_override_id < UNKNOWN_PANEL) { + panel_id = panel_override_id; + printk(BIOS_INFO, "OEM panel override:%s\n", + panel_name); + goto panel_init; + } + } + + switch (hw_id) { + case HW_PLATFORM_PROTO: + panel_id = SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_PANEL; + pinfo->has_bridge_chip = true; + break; + case HW_PLATFORM_MTP: + default: + printk(BIOS_ERR, "Display not enabled for %d HW type\n" + , hw_id); + return PANEL_TYPE_UNKNOWN; + } + +panel_init: + if (pinfo->has_bridge_chip) { + ret = oem_panel_bridge_chip_init(pinfo); + if (ret) { + printk(BIOS_ERR, "Error initializing bridge chip\n"); + return ret; + } + } + return init_panel_data(panelstruct, pinfo, phy_db); +} diff --git a/src/soc/qualcomm/sc7180/include/soc/display.h b/src/soc/qualcomm/sc7180/include/soc/display.h new file mode 100644 index 0000000..20cd748 --- /dev/null +++ b/src/soc/qualcomm/sc7180/include/soc/display.h @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2018 Qualcomm Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __SOC_QCOM_SC7180_DISPLAY_H__ +#define __SOC_QCOM_SC7180_DISPLAY_H__ + +#include <edid.h> + +void sc7180_display_init(struct device *dev); +int display_init(const char *panel_name, uint32_t rev, struct edid *ed); + +#endif + diff --git a/src/soc/qualcomm/sc7180/include/soc/display/panel_sn65dsix6_auo_bll6xak01_dsi_video.h b/src/soc/qualcomm/sc7180/include/soc/display/panel_sn65dsix6_auo_bll6xak01_dsi_video.h new file mode 100644 index 0000000..a783e03 --- /dev/null +++ b/src/soc/qualcomm/sc7180/include/soc/display/panel_sn65dsix6_auo_bll6xak01_dsi_video.h @@ -0,0 +1,281 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2020 Qualcomm Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _PANEL_SN65DSIX6_AUO_BLL6XAK01_DSI_VIDEO_H_ +#define _PANEL_SN65DSIX6_AUO_BLL6XAK01_DSI_VIDEO_H_ + +#include "panel.h" + +static char panel_node_id[256] = "qcom,dsi_sn65dsix6_auo_b116xak01_video"; +static char panel_controller[256] = "dsi:0:"; /* panel_controller */ +static char panel_compatible[256] = "qcom,mdss-dsi-panel"; +static char panel_destination[256] = "DISPLAY_1"; +static char slave_panel_node_id[256] = "qcom,dsi_sn65dsix6_auo_b116xak01_video"; + +static struct panel_config sn65dsix6_auo_b116xak01_dsi_video_panel_data = { + panel_node_id, + panel_controller, + panel_compatible, + 10, /* panel_interface */ + 0, /* panel_type */ + panel_destination, + 0, /* panel_orientation */ + 0, /* panel_clockrate */ + 60, /* panel_framerate */ + 0, /* panel_channelid */ + 0, /* dsi_virtualchannel_id */ + 0, /* panel_broadcast_mode */ + 0, /* panel_lp11_init */ + 0, /* panel_init_delay */ + 0, /* dsi_stream */ + 0, /* interleave_mode */ + 0, /* panel_bitclock_freq */ + 0, /* panel_operating_mode */ + 0, /* panel_with_enable_gpio */ + 0, /* mode_gpio_state */ + slave_panel_node_id, +}; + +static struct panel_resolution sn65dsix6_auo_b116xak01_dsi_video_panel_res = { + 1366, /* panel_width .*/ + 768, /* panel_height .*/ + 48, /* hfront_porch .*/ + 10, /* hback_porch .*/ + 32, /* hpulse_width .*/ + 0, /* hsync_skew .*/ + 4, /* vfront_porch .*/ + 15, /* vback_porch .*/ + 6, /* vpulse_width .*/ + 0, /* hleft_border .*/ + 0, /* hright_border .*/ + 0, /* vtop_border .*/ + 0, /* vbottom_border .*/ + 0, /* hactive_res */ + 0, /* uint16_t vactive_res */ + 0, /* invert_data_polarity */ + 0, /* invert_vsync_polarity */ + 0, /* invert_hsync_polarity */ +}; + +static struct color_info sn65dsix6_auo_b116xak01_dsi_video_color = { + 24, /* color_format */ + 0, /* color_order */ + 0, /* underflow_color */ + 0, /* border_color */ + 0, /* pixel_packing */ + 0, /* pixel_alignment */ +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd1[] = { + 0x5c, 0x01, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd2[] = { + 0x0a, 0x02, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd3[] = { + 0x10, 0x20, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd4[] = { + 0x12, 0x29, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd5[] = { + 0x5a, 0x05, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd6[] = { + 0x93, 0x10, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd7[] = { + 0x94, 0x81, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd8[] = { + 0x0d, 0x01, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd9[] = { + 0x64, 0x01, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd10[] = { + 0x74, 0x00, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd11[] = { + 0x75, 0x01, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd12[] = { + 0x76, 0x0a, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd13[] = { + 0x77, 0x01, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd14[] = { + 0x78, 0x81, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd15[] = { + 0x96, 0x0a, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd16[] = { + 0x20, 0x56, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd17[] = { + 0x21, 0x05, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd18[] = { + 0x24, 0x00, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd19[] = { + 0x25, 0x03, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd20[] = { + 0x2c, 0x20, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd21[] = { + 0x2d, 0x00, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd22[] = { + 0x30, 0x06, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd23[] = { + 0x31, 0x00, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd24[] = { + 0x34, 0x0a, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd25[] = { + 0x36, 0x0f, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd26[] = { + 0x38, 0x30, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd27[] = { + 0x3a, 0x04, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd28[] = { + 0x5b, 0x01, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd29[] = { + 0x3c, 0x00, 0x23, 0x80 +}; + +static char sn65dsix6_auo_b116xak01_dsi_video_on_cmd30[] = { + 0x5a, 0x0d, 0x23, 0x80 +}; + +static struct mipi_dsi_cmd sn65dsix6_auo_b116xak01_dsi_video_on_command[] = { + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd1, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd2, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd3, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd4, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd5, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd6, 0xff}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd7, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd8, 0xff}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd9, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd10, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd11, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd12, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd13, 0xff}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd14, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd15, 0xff}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd16, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd17, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd18, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd19, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd20, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd21, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd22, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd23, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd24, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd25, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd26, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd27, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd28, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd29, 0x10}, + {0x4, sn65dsix6_auo_b116xak01_dsi_video_on_cmd30, 0x10}, +}; + +#define SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_ON_COMMAND 30 + +static struct mipi_dsi_cmd sn65dsix6_auo_b116xak01_dsi_video_off_command[] = { +}; + +#define SN65DSIX6_AUO_B116XAK01_DSI_VIDEO_OFF_COMMAND 0 + +static struct command_state sn65dsix6_auo_b116xak01_dsi_video_state = { + 0, 1 +}; + +static struct commandpanel_info sn65dsix6_auo_b116xak01_dsi_video_command_panel = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static struct videopanel_info sn65dsix6_auo_b116xak01_dsi_video_panel = { + 0, /* hsync_pulse */ + 0, /* hfp_power_mode */ + 0, /* hbp_power_mode */ + 0, /* hsa_power_mode */ + 1, /* bllp_eof_power_mode */ + 1, /* bllp_power_mode */ + 0, /* traffic_mode */ + 0, /* dma_delayafter_vsync */ + 0x9, /* bllp_eof_power */ +}; + +static struct lane_configuration sn65dsix6_auo_b116xak01_dsi_video_lane_config = { +/* For Proto0, due to the incorrect schematic we have to set + force_clk_lane_hs because we are supporting only 384Mhz continuous clock +*/ + 4, 0, 1, 1, 1, 1, 1 +}; + +static const uint32_t sn65dsix6_auo_b116xak01_dsi_video_timings[] = { + 0x0, 0x11, 0x3, 0x5, 0x1E, 0x1E, 0x4, 0x4, 0x2, 0x3, 0x4 +}; + +static struct panel_timing sn65dsix6_auo_b116xak01_dsi_video_timing_info = { + 0x0, 0x04, 0x0c, 0x2d +}; + +static struct panel_reset_sequence + sn65dsix6_auo_b116xak01_dsi_video_panel_reset_seq = { + {1, 0, 1, }, {20, 20, 50, }, 2 +}; + +#endif diff --git a/src/soc/qualcomm/sc7180/soc.c b/src/soc/qualcomm/sc7180/soc.c index fbcfc6e..c0b11ae 100644 --- a/src/soc/qualcomm/sc7180/soc.c +++ b/src/soc/qualcomm/sc7180/soc.c @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (C) 2018-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,6 +19,7 @@ #include <soc/mmu_common.h> #include <soc/symbols.h> #include <soc/aop.h> +#include <soc/display.h> static void soc_read_resources(struct device *dev) { @@ -33,6 +34,9 @@ static void soc_init(struct device *dev) { aop_fw_load_reset(); +#if CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT) + sc7180_display_init(dev); +#endif } static struct device_operations soc_ops = { -- To view, visit
https://review.coreboot.org/c/coreboot/+/39615
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I7d5e3f1781c48759553243abeb3d694f76cd008e Gerrit-Change-Number: 39615 Gerrit-PatchSet: 1 Gerrit-Owner: Ravi kumar <rbokka(a)codeaurora.org> Gerrit-Reviewer: Martin Roth <martinroth(a)google.com> Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com> Gerrit-MessageType: newchange
9
53
0
0
Change in coreboot[master]: sc7180: Add support for sn65dsi86 bridge.
by Ravi kumar (Code Review)
10 Sep '20
10 Sep '20
Ravi kumar has uploaded this change for review. (
https://review.coreboot.org/c/coreboot/+/42899
) Change subject: sc7180: Add support for sn65dsi86 bridge. ...................................................................... sc7180: Add support for sn65dsi86 bridge. Add sn65dsi86 bridge driver to enable the eDP bridge. Change-Id: I36a68f3241f0ba316c261a73c2f6d30fe6c3ccdc Signed-off-by: Vinod Polimera <vpolimer(a)codeaurora.org> --- A src/drivers/ti/sn65dsi86bridge/Kconfig A src/drivers/ti/sn65dsi86bridge/Makefile.inc A src/drivers/ti/sn65dsi86bridge/sn65dsi86bridge.c A src/drivers/ti/sn65dsi86bridge/sn65dsi86bridge.h 4 files changed, 548 insertions(+), 0 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/99/42899/1 diff --git a/src/drivers/ti/sn65dsi86bridge/Kconfig b/src/drivers/ti/sn65dsi86bridge/Kconfig new file mode 100644 index 0000000..1a37409 --- /dev/null +++ b/src/drivers/ti/sn65dsi86bridge/Kconfig @@ -0,0 +1,7 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config DRIVERS_TI_SN65DSI86BRIDGE + bool + default y + help + TI SN65DSI86BRIDGE diff --git a/src/drivers/ti/sn65dsi86bridge/Makefile.inc b/src/drivers/ti/sn65dsi86bridge/Makefile.inc new file mode 100644 index 0000000..c46eb6d --- /dev/null +++ b/src/drivers/ti/sn65dsi86bridge/Makefile.inc @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_DRIVERS_TI_SN65DSI86BRIDGE) += sn65dsi86bridge.c \ No newline at end of file diff --git a/src/drivers/ti/sn65dsi86bridge/sn65dsi86bridge.c b/src/drivers/ti/sn65dsi86bridge/sn65dsi86bridge.c new file mode 100644 index 0000000..3fda4f9 --- /dev/null +++ b/src/drivers/ti/sn65dsi86bridge/sn65dsi86bridge.c @@ -0,0 +1,398 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <delay.h> +#include <endian.h> +#include <device/i2c_simple.h> +#include <edid.h> +#include <timer.h> +#include <types.h> +#include <soc/addressmap.h> +#include "sn65dsi86bridge.h" + +#define bridge_debug(x...) do {if (0) printk(BIOS_DEBUG, x); } while (0) + +#define BRIDGE_GETHIGHERBYTE(x) (uint8_t)((x&0xFF00)>>8) +#define BRIDGE_GETLOWERBYTE(x) (uint8_t)((x&0x00FF)) + +/* fudge factor required to account for 8b/10b encoding */ +#define DP_CLK_FUDGE_NUM 10 +#define DP_CLK_FUDGE_DEN 8 + +/* DPCD */ +#define DP_BRIDGE_DPCD_REV 0x700 +#define DP_BRIDGE_11 0x00 +#define DP_BRIDGE_12 0x01 +#define DP_BRIDGE_13 0x02 +#define DP_BRIDGE_14 0x03 +#define DP_BRIDGE_CONFIGURATION_SET 0x10a +#define DP_MAX_LINK_RATE 0x001 +#define DP_MAX_LANE_COUNT 0x002 +#define DP_SUPPORTED_LINK_RATES 0x010 /* eDP 1.4 */ +#define DP_MAX_LINK_RATE 0x001 +#define DP_MAX_SUPPORTED_RATES 8 /* 16-bit little-endian */ + +/* link configuration */ +#define DP_LINK_BW_SET 0x100 +#define DP_LINK_BW_1_62 0x06 +#define DP_LINK_BW_2_7 0x0a +#define DP_LINK_BW_5_4 0x14 + +#define AUX_CMD_SEND 0x1 +#define MIN_DSI_CLK_FREQ_MHZ 40 + +/* + * LUT index corresponds to register value and + * LUT values corresponds to dp data rate supported + * by the bridge in Mbps unit. + */ +static const unsigned int sn65dsi86_bridge_dp_rate_lut[] = { + 0, 1620, 2160, 2430, 2700, 3240, 4320, 5400 +}; + +enum cb_err sn65dsi86_bridge_read_edid(uint8_t bus, uint8_t chip, struct edid *out) +{ + int ret; + u8 edid[EDID_LENGTH * 2]; + int edid_size = EDID_LENGTH; + + /* Send I2C command to Disable the HPD */ + i2c_writeb(bus, chip, SN_HPD_DISABLE_REG, 0x1); + + /* Send I2C command to claim EDID I2c slave */ + i2c_writeb(bus, chip, I2C_CLAIM_ADDR_EN1, (EDID_I2C_ADDR << 1) | 0x1); + + /* read EDID */ + ret = i2c_read_bytes(bus, EDID_I2C_ADDR, 0x0, edid, EDID_LENGTH); + if (ret != 0) { + printk(BIOS_ERR, "ERROR: Failed to read EDID.\n"); + return CB_ERR; + } + + if (edid[EDID_EXTENSION_FLAG]) { + edid_size += EDID_LENGTH; + ret = i2c_read_bytes(bus, EDID_I2C_ADDR, EDID_LENGTH, + &edid[EDID_LENGTH], EDID_LENGTH); + if (ret != 0) { + printk(BIOS_ERR, "Failed to read EDID ext block.\n"); + return CB_ERR; + } + } + + if (decode_edid(edid, edid_size, out) != EDID_CONFORMANT) { + printk(BIOS_ERR, "ERROR: Failed to decode EDID.\n"); + return CB_ERR; + } + + return CB_SUCCESS; +} + +static void sn65dsi86_bridge_dpcd_request(uint8_t bus, + uint8_t chip, + unsigned int dpcd_reg, + unsigned int len, + enum dpcd_request request, + uint8_t *data) +{ + int i; + uint32_t length; + uint8_t buf; + uint8_t reg; + + while (len) { + length = MIN(len, 16); + + i2c_writeb(bus, chip, SN_AUX_ADDR_19_16_REG, (dpcd_reg >> 16) & 0xF); + i2c_writeb(bus, chip, SN_AUX_ADDR_15_8_REG, (dpcd_reg >> 8) & 0xFF); + i2c_writeb(bus, chip, SN_AUX_ADDR_7_0_REG, (dpcd_reg) & 0xFF); + i2c_writeb(bus, chip, SN_AUX_LENGTH_REG, length); /* size of 1 Byte data */ + if (request == DPCD_WRITE) { + reg = SN_AUX_WDATA_REG_0; + for (i = 0; i < length; i++) + i2c_writeb(bus, chip, reg++, *data++); + + i2c_writeb(bus, chip, + SN_AUX_CMD_REG, AUX_CMD_SEND | (NATIVE_AUX_WRITE << 4)); + } else { + i2c_writeb(bus, chip, + SN_AUX_CMD_REG, AUX_CMD_SEND | (NATIVE_AUX_READ << 4)); + if (!wait_ms(100, + !i2c_readb(bus, chip, SN_AUX_CMD_REG, + &buf) && !(buf & AUX_CMD_SEND))) { + printk(BIOS_ERR, "ERROR: aux command send failed\n"); + } + + reg = SN_AUX_RDATA_REG_0; + for (i = 0; i < length; i++) { + i2c_readb(bus, chip, reg++, &buf); + *data++ = buf; + } + } + + len -= length; + } +} + +static void sn65dsi86_bridge_valid_dp_rates(uint8_t bus, uint8_t chip, bool rate_valid[]) +{ + unsigned int rate_per_200khz; + unsigned int rate_mhz; + uint8_t dpcd_val; + int i, j; + + sn65dsi86_bridge_dpcd_request(bus, chip, + DP_BRIDGE_DPCD_REV, 1, DPCD_READ, &dpcd_val); + if (dpcd_val >= DP_BRIDGE_14) { + /* eDP 1.4 devices must provide a custom table */ + uint8_t sink_rates[DP_MAX_SUPPORTED_RATES * 2]; + + sn65dsi86_bridge_dpcd_request(bus, chip, DP_SUPPORTED_LINK_RATES, + ARRAY_SIZE(sink_rates), + DPCD_READ, sink_rates); + for (i = 0; i < ARRAY_SIZE(sink_rates); i++) { + rate_per_200khz = le16_to_cpu(sink_rates[i]); + + if (!rate_per_200khz) + break; + + rate_mhz = rate_per_200khz * 200 / 1000; + for (j = 0; + j < ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut); + j++) { + if (sn65dsi86_bridge_dp_rate_lut[j] == rate_mhz) + rate_valid[j] = true; + } + } + + for (i = 0; i < ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut); i++) { + if (rate_valid[i]) + return; + } + + printk(BIOS_ERR, "No matching eDP rates in table; falling back\n"); + } + + /* On older versions best we can do is use DP_MAX_LINK_RATE */ + sn65dsi86_bridge_dpcd_request(bus, chip, + DP_MAX_LINK_RATE, 1, DPCD_READ, &dpcd_val); + + switch (dpcd_val) { + default: + printk(BIOS_ERR, + "Unexpected max rate (%#x); assuming 5.4 GHz\n", + (int)dpcd_val); + /* fall through */ + case DP_LINK_BW_5_4: + rate_valid[7] = 1; + /* fall through */ + case DP_LINK_BW_2_7: + rate_valid[4] = 1; + /* fall through */ + case DP_LINK_BW_1_62: + rate_valid[1] = 1; + break; + } +} + +static void sn65dsi86_bridge_set_dsi_clock_range(uint8_t bus, uint8_t chip, + struct edid *edid, + int num_of_lanes, int bpp) +{ + uint64_t pixel_clk_hz; + uint64_t stream_bit_rate_mhz; + uint64_t min_req_dsi_clk; + + pixel_clk_hz = edid->mode.pixel_clock * 1000; + stream_bit_rate_mhz = (pixel_clk_hz / 1000000) * bpp; + + /* For TI the clock frequencies are half the bit rates */ + min_req_dsi_clk = stream_bit_rate_mhz / (num_of_lanes * 2); + + /* for each increment in val, frequency increases by 5MHz */ + min_req_dsi_clk = (MIN_DSI_CLK_FREQ_MHZ / 5) + + (((min_req_dsi_clk - MIN_DSI_CLK_FREQ_MHZ) / 5) & 0xFF); + + i2c_writeb(bus, chip, SN_DSIA_CLK_FREQ_REG, min_req_dsi_clk); +} + +static void sn65dsi86_bridge_set_dp_clock_range(uint8_t bus, uint8_t chip, + struct edid *edid, int num_of_lanes) +{ + uint64_t stream_bit_rate_khz; + bool rate_valid[ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut)] = { }; + uint64_t dp_rate_mhz; + int dp_rate_idx, i; + + stream_bit_rate_khz = edid->mode.pixel_clock * 18; + + /* Calculate minimum DP data rate, taking 80% as per DP spec */ + dp_rate_mhz = DIV_ROUND_UP(stream_bit_rate_khz * DP_CLK_FUDGE_NUM, + 1000 * num_of_lanes * DP_CLK_FUDGE_DEN); + + for (i = 0; i < ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut) - 1; i++) + if (sn65dsi86_bridge_dp_rate_lut[i] > dp_rate_mhz) + break; + + sn65dsi86_bridge_valid_dp_rates(bus, chip, rate_valid); + + /* Train until we run out of rates */ + for (dp_rate_idx = i; + dp_rate_idx < ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut); + dp_rate_idx++) + if (rate_valid[dp_rate_idx]) + break; + + if(dp_rate_idx < ARRAY_SIZE(sn65dsi86_bridge_dp_rate_lut)) + i2c_write_field(bus, chip, SN_DATARATE_CONFIG_REG, dp_rate_idx, 8, 5); + else + printk(BIOS_ERR, "ERROR: valid dp rate not found"); +} + +static void sn65dsi86_bridge_set_bridge_active_timing(uint8_t bus, + uint8_t chip, + struct edid *edid) +{ + i2c_writeb(bus, chip, SN_CHA_ACTIVE_LINE_LENGTH_LOW_REG, + BRIDGE_GETLOWERBYTE(edid->mode.ha)); + i2c_writeb(bus, chip, SN_CHA_ACTIVE_LINE_LENGTH_HIGH_REG, + BRIDGE_GETHIGHERBYTE(edid->mode.ha)); + i2c_writeb(bus, chip, SN_CHA_VERTICAL_DISPLAY_SIZE_LOW_REG, + BRIDGE_GETLOWERBYTE(edid->mode.va)); + i2c_writeb(bus, chip, SN_CHA_VERTICAL_DISPLAY_SIZE_HIGH_REG, + BRIDGE_GETHIGHERBYTE(edid->mode.va)); + i2c_writeb(bus, chip, SN_CHA_HSYNC_PULSE_WIDTH_LOW_REG, + BRIDGE_GETLOWERBYTE(edid->mode.hspw)); + i2c_writeb(bus, chip, SN_CHA_HSYNC_PULSE_WIDTH_HIGH_REG, + BRIDGE_GETHIGHERBYTE(edid->mode.hspw)); + i2c_writeb(bus, chip, SN_CHA_VSYNC_PULSE_WIDTH_LOW_REG, + BRIDGE_GETLOWERBYTE(edid->mode.vspw)); + i2c_writeb(bus, chip, SN_CHA_VSYNC_PULSE_WIDTH_HIGH_REG, + BRIDGE_GETHIGHERBYTE(edid->mode.vspw)); + i2c_writeb(bus, chip, SN_CHA_HORIZONTAL_BACK_PORCH_REG, + edid->mode.hbl - edid->mode.hso - edid->mode.hspw); + i2c_writeb(bus, chip, SN_CHA_VERTICAL_BACK_PORCH_REG, + edid->mode.vbl - edid->mode.vso - edid->mode.vspw); + i2c_writeb(bus, chip, SN_CHA_HORIZONTAL_FRONT_PORCH_REG, + edid->mode.hso); + i2c_writeb(bus, chip, SN_CHA_VERTICAL_FRONT_PORCH_REG, + edid->mode.vso); +} + +static void sn65dsi86_bridge_link_training(uint8_t bus, uint8_t chip) +{ + uint8_t buf; + + /* enable pll lock */ + i2c_writeb(bus, chip, SN_PLL_ENABLE_REG, 0x1); + + if (!wait_ms(500, + !(i2c_readb(bus, chip, SN_DPPLL_SRC_REG, &buf)) && + (buf & BIT(7)))) { + printk(BIOS_ERR, "ERROR: PLL lock failure\n"); + } + + /* + * The SN65DSI86 only supports ASSR Display Authentication method and + * this method is enabled by default. An eDP panel must support this + * authentication method. We need to enable this method in the eDP panel + * at DisplayPort address 0x0010A prior to link training. + */ + buf = 0x1; + sn65dsi86_bridge_dpcd_request(bus, chip, + DP_BRIDGE_CONFIGURATION_SET, 1, DPCD_WRITE, &buf); + + /* semi auto link training mode */ + i2c_writeb(bus, chip, SN_ML_TX_MODE_REG, 0xa); + + if (!wait_ms(500, + !(i2c_readb(bus, chip, SN_ML_TX_MODE_REG, &buf)) && + (buf & NORMAL_MODE))) { + printk(BIOS_ERR, "ERROR: Link training failed"); + } + +} + +static enum cb_err sn65dsi86_bridge_get_plug_in_status(uint8_t bus, uint8_t chip) +{ + int val; + uint8_t buf; + + val = i2c_readb(bus, chip, SN_HPD_DISABLE_REG, &buf); + if (val == 0 && (buf & HPD_DISABLE)) + return CB_SUCCESS; + + return CB_ERR; +} + +/* + * support bridge HPD function + * some hardware version do not support bridge hdp, + * we use 360ms to try to get the hpd single now, + * if we can not get bridge hpd single, it will delay 360ms, + * also meet the bridge power timing request, to compatible + * all of the hardware version + */ +static void sn65dsi86_bridge_wait_hpd(uint8_t bus, uint8_t chip) +{ + if (wait_ms(360, sn65dsi86_bridge_get_plug_in_status(bus, chip))) + return; + + printk(BIOS_WARNING, "HPD detection failed, force hpd\n"); + + /* Force HPD */ + i2c_write_field(bus, chip, SN_HPD_DISABLE_REG, HPD_DISABLE, 1, 0 ); +} + +static void sn65dsi86_bridge_assr_config(uint8_t bus, uint8_t chip, int enable) +{ + if (enable) + i2c_write_field(bus, chip, SN_ENH_FRAME_REG, VSTREAM_ENABLE, 1, 3); + else + i2c_write_field(bus, chip, SN_ENH_FRAME_REG, VSTREAM_DISABLE, 1, 3); +} + +static int sn65dsi86_bridge_dp_lane_config(uint8_t bus, uint8_t chip) +{ + uint8_t data; + + sn65dsi86_bridge_dpcd_request(bus, chip, DP_MAX_LANE_COUNT, 1, DPCD_READ, &data); + i2c_write_field(bus, chip, SN_SSC_CONFIG_REG, MIN(data, 3), 3, 4); + + return data; +} + +void sn65dsi86_bridge_init(uint8_t bus, uint8_t chip, + struct edid *edid, uint32_t num_of_lanes, + uint8_t ref_clk, uint32_t bpp) +{ + int dp_lanes; + + sn65dsi86_bridge_wait_hpd(bus, chip); + + /* set refclk to 19.2 MHZ */ + i2c_write_field(bus, chip, SN_DPPLL_SRC_REG, ref_clk, 7, 1); + + /* DSI Lanes config */ + i2c_write_field(bus, chip, SN_DSI_LANES_REG, (4 - num_of_lanes), 3, 3); + + /* DP Lane config */ + dp_lanes = sn65dsi86_bridge_dp_lane_config(bus, chip); + + sn65dsi86_bridge_set_dsi_clock_range(bus, chip, edid, num_of_lanes ,bpp); + + sn65dsi86_bridge_set_dp_clock_range(bus, chip, edid, dp_lanes); + + /* Disable vstream */ + sn65dsi86_bridge_assr_config(bus, chip, 0); + sn65dsi86_bridge_link_training(bus, chip); + sn65dsi86_bridge_set_bridge_active_timing(bus, chip, edid); + + /* DP BPP config */ + i2c_writeb(bus, chip, SN_DATA_FORMAT_REG, (uint8_t)0x01); + + /* color bar disabled */ + i2c_writeb(bus, chip, SN_COLOR_BAR_REG, 0x5); + + /* Enable vstream */ + sn65dsi86_bridge_assr_config(bus, chip, 1); +} diff --git a/src/drivers/ti/sn65dsi86bridge/sn65dsi86bridge.h b/src/drivers/ti/sn65dsi86bridge/sn65dsi86bridge.h new file mode 100644 index 0000000..b8a9b6e --- /dev/null +++ b/src/drivers/ti/sn65dsi86bridge/sn65dsi86bridge.h @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __TI_SN65DSI86BRIDGE_H +#define __TI_SN65DSI86BRIDGE_H + +#include <edid.h> + +enum bridge_regs { + SN_DPPLL_SRC_REG = 0x0A, + SN_PLL_ENABLE_REG = 0x0D, + SN_DSI_LANES_REG = 0x10, + SN_DSIA_CLK_FREQ_REG = 0x12, + SN_CHA_ACTIVE_LINE_LENGTH_LOW_REG = 0x20, + SN_CHA_ACTIVE_LINE_LENGTH_HIGH_REG = 0x21, + SN_CHA_VERTICAL_DISPLAY_SIZE_LOW_REG = 0x24, + SN_CHA_VERTICAL_DISPLAY_SIZE_HIGH_REG = 0x25, + SN_CHA_HSYNC_PULSE_WIDTH_LOW_REG = 0x2C, + SN_CHA_HSYNC_PULSE_WIDTH_HIGH_REG = 0x2D, + SN_CHA_VSYNC_PULSE_WIDTH_LOW_REG = 0x30, + SN_CHA_VSYNC_PULSE_WIDTH_HIGH_REG = 0x31, + SN_CHA_HORIZONTAL_BACK_PORCH_REG = 0x34, + SN_CHA_VERTICAL_BACK_PORCH_REG = 0x36, + SN_CHA_HORIZONTAL_FRONT_PORCH_REG = 0x38, + SN_CHA_VERTICAL_FRONT_PORCH_REG = 0x3A, + SN_COLOR_BAR_REG = 0x3C, + SN_ENH_FRAME_REG = 0x5A, + SN_DATA_FORMAT_REG = 0x5B, + SN_HPD_DISABLE_REG = 0x5C, + SN_AUX_WDATA_REG_0 = 0x64, + SN_AUX_WDATA_REG_1 = 0x65, + SN_AUX_WDATA_REG_2 = 0x66, + SN_AUX_WDATA_REG_3 = 0x67, + SN_AUX_WDATA_REG_4 = 0x68, + SN_AUX_WDATA_REG_5 = 0x69, + SN_AUX_WDATA_REG_6 = 0x6A, + SN_AUX_WDATA_REG_7 = 0x6B, + SN_AUX_WDATA_REG_8 = 0x6C, + SN_AUX_WDATA_REG_9 = 0x6D, + SN_AUX_WDATA_REG_10 = 0x6E, + SN_AUX_WDATA_REG_11 = 0x6F, + SN_AUX_WDATA_REG_12 = 0x70, + SN_AUX_WDATA_REG_13 = 0x71, + SN_AUX_WDATA_REG_14 = 0x72, + SN_AUX_WDATA_REG_15 = 0x73, + SN_AUX_ADDR_19_16_REG = 0x74, + SN_AUX_ADDR_15_8_REG = 0x75, + SN_AUX_ADDR_7_0_REG = 0x76, + SN_AUX_LENGTH_REG = 0x77, + SN_AUX_CMD_REG = 0x78, + SN_AUX_RDATA_REG_0 = 0x79, + SN_AUX_RDATA_REG_1 = 0x7A, + SN_AUX_RDATA_REG_2 = 0x7B, + SN_AUX_RDATA_REG_3 = 0x7C, + SN_AUX_RDATA_REG_4 = 0x7D, + SN_AUX_RDATA_REG_5 = 0x7E, + SN_AUX_RDATA_REG_6 = 0x7F, + SN_AUX_RDATA_REG_7 = 0x80, + SN_AUX_RDATA_REG_8 = 0x81, + SN_AUX_RDATA_REG_9 = 0x82, + SN_AUX_RDATA_REG_10 = 0x83, + SN_AUX_RDATA_REG_11 = 0x84, + SN_AUX_RDATA_REG_12 = 0x85, + SN_AUX_RDATA_REG_13 = 0x86, + SN_AUX_RDATA_REG_14 = 0x87, + SN_AUX_RDATA_REG_15 = 0x88, + SN_SSC_CONFIG_REG = 0x93, + SN_DATARATE_CONFIG_REG = 0x94, + SN_ML_TX_MODE_REG = 0x96, + SN_AUX_CMD_STATUS_REG = 0xF4, +}; + +enum { + HPD_ENABLE = 0x0, + HPD_DISABLE = 0x1 , +}; + +enum { + SOT_ERR_TOL_DSI = 0x0, + CHB_DSI_LANES = 0x1, + CHA_DSI_LANES = 0x2, + DSI_CHANNEL_MODE = 0x3, + LEFT_RIGHT_PIXELS = 0x4, +}; + +enum vstream_config { + VSTREAM_DISABLE = 0, + VSTREAM_ENABLE = 1, +}; + +enum dp_pll_clk_src { + SN65_SEL_12MHZ = 0x0, + SN65_SEL_19MHZ = 0x1, + SN65_SEL_26MHZ = 0x2, + SN65_SEL_27MHZ = 0x3, + SN65_SEL_38MHZ = 0x4, +}; + +enum i2c_over_aux { + I2C_OVER_AUX_WRITE_MOT_0 = 0x0, + I2C_OVER_AUX_READ_MOT_0 = 0x1, + I2C_OVER_AUX_WRITE_STATUS_UPDATE_0 = 0x4, + I2C_OVER_AUX_WRITE_MOT_1 = 0x5, + I2C_OVER_AUX_READ_MOT_1 = 0x6, + I2C_OVER_AUX_WRITE_STATUS_UPDATE_1 = 0x7, + NATIVE_AUX_WRITE = 0x8, + NATIVE_AUX_READ = 0x9, +}; + +enum ml_tx_mode { + MAIN_LINK_OFF = 0x0, + NORMAL_MODE = 0x1, + TPS1 = 0x2, + TPS2 = 0x3, + TPS3 = 0x4, + PRBS7 = 0x5, + HBR2_COMPLIANCE_EYE_PATTERN = 0x6, + SYMBOL_ERR_RATE_MEASUREMENT_PATTERN = 0x7, + CUTSOM_PATTERN = 0x8, + FAST_LINK_TRAINING = 0x9, + SEMI_AUTO_LINK_TRAINING = 0xa, + REDRIVER_SEMI_AUTO_LINK_TRAINING = 0xb, +}; + +enum dpcd_request { + DPCD_READ = 0x0, + DPCD_WRITE = 0x1, +}; + +enum { + EDID_LENGTH = 128, + EDID_I2C_ADDR = 0x50, + I2C_CLAIM_ADDR_EN1 = 0x60, + EDID_EXTENSION_FLAG = 0x7e, +}; + +void sn65dsi86_bridge_init(uint8_t bus, uint8_t chip, + struct edid *edid, uint32_t num_of_lines, + uint8_t ref_clk, uint32_t bpp); +enum cb_err sn65dsi86_bridge_read_edid(uint8_t bus, uint8_t chip, struct edid *out); +#endif -- To view, visit
https://review.coreboot.org/c/coreboot/+/42899
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I36a68f3241f0ba316c261a73c2f6d30fe6c3ccdc Gerrit-Change-Number: 42899 Gerrit-PatchSet: 1 Gerrit-Owner: Ravi kumar <rbokka(a)codeaurora.org> Gerrit-Reviewer: Martin Roth <martinroth(a)google.com> Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com> Gerrit-MessageType: newchange
7
31
0
0
Change in coreboot[master]: mb/intel/tglrvp: Enable HECI interface
by Tim Wawrzynczak (Code Review)
10 Sep '20
10 Sep '20
Tim Wawrzynczak has posted comments on this change. (
https://review.coreboot.org/c/coreboot/+/42307
) Change subject: mb/intel/tglrvp: Enable HECI interface ...................................................................... Patch Set 6: Code-Review+2 -- To view, visit
https://review.coreboot.org/c/coreboot/+/42307
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I23117fa96503942e6a72765dd3fd1cc762e3f705 Gerrit-Change-Number: 42307 Gerrit-PatchSet: 6 Gerrit-Owner: Jamie Ryu <jamie.m.ryu(a)intel.com> Gerrit-Reviewer: Angel Pons <th3fanbus(a)gmail.com> Gerrit-Reviewer: Furquan Shaikh <furquan(a)google.com> Gerrit-Reviewer: Jamie Ryu <jamie.m.ryu(a)intel.com> Gerrit-Reviewer: Nick Vaccaro <nvaccaro(a)google.com> Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com> Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org> Gerrit-Reviewer: Raj Astekar <raj.astekar(a)intel.com> Gerrit-Reviewer: Rizwan Qureshi <rizwan.qureshi(a)intel.com> Gerrit-Reviewer: Tim Wawrzynczak <twawrzynczak(a)chromium.org> Gerrit-Reviewer: Tim Wawrzynczak <twawrzynczak(a)google.com> Gerrit-Reviewer: Wonkyu Kim <wonkyu.kim(a)intel.com> Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org> Gerrit-CC: Paul Menzel <paulepanter(a)users.sourceforge.net> Gerrit-Comment-Date: Thu, 10 Sep 2020 00:25:31 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment
1
0
0
0
Change in coreboot[master]: sc7180: enable bl31
by mturney mturney (Code Review)
10 Sep '20
10 Sep '20
Hello ashk(a)codeaurora.org, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/35504
to review the following change. Change subject: sc7180: enable bl31 ...................................................................... sc7180: enable bl31 Developer/Reviewer, be aware of this patch from Napali:
https://review.coreboot.org/c/coreboot/+/28014/44
Change-Id: Ia961ee0e30478e21fd786ce464655977449df510 Signed-off-by: ashk <ashk(a)codeaurora.org> --- M src/soc/qualcomm/sc7180/Kconfig M src/soc/qualcomm/sc7180/include/soc/memlayout.ld 2 files changed, 2 insertions(+), 1 deletion(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/04/35504/1 diff --git a/src/soc/qualcomm/sc7180/Kconfig b/src/soc/qualcomm/sc7180/Kconfig index df5d116..28f7522 100644 --- a/src/soc/qualcomm/sc7180/Kconfig +++ b/src/soc/qualcomm/sc7180/Kconfig @@ -6,6 +6,7 @@ select ARCH_RAMSTAGE_ARMV8_64 select ARCH_ROMSTAGE_ARMV8_64 select ARCH_VERSTAGE_ARMV8_64 + select ARM64_USE_ARM_TRUSTED_FIRMWARE select GENERIC_GPIO_LIB select GENERIC_UDELAY select HAVE_MONOTONIC_TIMER diff --git a/src/soc/qualcomm/sc7180/include/soc/memlayout.ld b/src/soc/qualcomm/sc7180/include/soc/memlayout.ld index f4e6f05..e47f881 100644 --- a/src/soc/qualcomm/sc7180/include/soc/memlayout.ld +++ b/src/soc/qualcomm/sc7180/include/soc/memlayout.ld @@ -72,7 +72,7 @@ REGION(dram_reserved1, 0x80820000, 0x20000, 0x1000) REGION(dram_reserved, 0x80900000, 0x200000, 0x1000) /* Various hardware/software subsystems make use of this area */ - BL31(0x85000000, 0x1A800000) + BL31(0x80C00000, 0x1A800000) POSTRAM_CBFS_CACHE(0x9F800000, 384K) RAMSTAGE(0x9F860000, 2M) } -- To view, visit
https://review.coreboot.org/c/coreboot/+/35504
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: Ia961ee0e30478e21fd786ce464655977449df510 Gerrit-Change-Number: 35504 Gerrit-PatchSet: 1 Gerrit-Owner: mturney mturney <mturney(a)codeaurora.org> Gerrit-Reviewer: Julius Werner <jwerner(a)chromium.org> Gerrit-Reviewer: ashk(a)codeaurora.org Gerrit-Reviewer: mturney mturney <mturney(a)codeaurora.org> Gerrit-MessageType: newchange
7
24
0
0
Change in coreboot[master]: HACK trogdor: Memlayout changed to support QcLib Size increase
by mturney mturney (Code Review)
10 Sep '20
10 Sep '20
Hello ashk(a)codeaurora.org, I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/36277
to review the following change. Change subject: HACK trogdor: Memlayout changed to support QcLib Size increase ...................................................................... HACK trogdor: Memlayout changed to support QcLib Size increase Change-Id: I49008ea9bc6254c745352b2e8ee965ddc2e8e5e4 Signed-off-by: Ashwin Kumar <ashk(a)codeaurora.org> --- M src/soc/qualcomm/sc7180/include/soc/memlayout.ld 1 file changed, 4 insertions(+), 4 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/77/36277/1 diff --git a/src/soc/qualcomm/sc7180/include/soc/memlayout.ld b/src/soc/qualcomm/sc7180/include/soc/memlayout.ld index ce260aa..6ca3e95 100644 --- a/src/soc/qualcomm/sc7180/include/soc/memlayout.ld +++ b/src/soc/qualcomm/sc7180/include/soc/memlayout.ld @@ -59,10 +59,10 @@ REGION(ddr_training, 0x14850000, 8K, 4K) REGION(qclib_serial_log, 0x14852000, 4K, 4K) REGION(ddr_information, 0x14853000, 1K, 1K) - REGION(dcb, 0x14870000, 16K, 4K) - REGION(pmic, 0x14874000, 44K, 4K) - REGION(limits_cfg, 0x1487F000, 4K, 4K) - REGION(qclib, 0x14880000, 512K, 4K) + REGION(dcb, 0x1485b000, 16K, 4K) + REGION(pmic, 0x1485f000, 44K, 4K) + REGION(limits_cfg, 0x1486a000, 4K, 4K) + REGION(qclib, 0x1486b000, 596K, 4K) BSRAM_END(0x14900000) DRAM_START(0x80000000) -- To view, visit
https://review.coreboot.org/c/coreboot/+/36277
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I49008ea9bc6254c745352b2e8ee965ddc2e8e5e4 Gerrit-Change-Number: 36277 Gerrit-PatchSet: 1 Gerrit-Owner: mturney mturney <mturney(a)codeaurora.org> Gerrit-Reviewer: ashk(a)codeaurora.org Gerrit-MessageType: newchange
6
22
0
0
Change in coreboot[master]: sc7180: Add display 10nm phy & pll programming support [Patch 1 of 3]
by Ravi kumar (Code Review)
10 Sep '20
10 Sep '20
Ravi kumar has uploaded this change for review. (
https://review.coreboot.org/c/coreboot/+/39613
) Change subject: sc7180: Add display 10nm phy & pll programming support [Patch 1 of 3] ...................................................................... sc7180: Add display 10nm phy & pll programming support [Patch 1 of 3] Adds basic headers as well as source required for display dsi 10nm phy & pll programming. Change-Id: I8ff400922ae594f558cf73a5aaa433a3a93347c2 Signed-off-by: Vinod Polimera <vpolimer(a)codeaurora.org> --- A src/soc/qualcomm/sc7180/display/dsi_phy.c A src/soc/qualcomm/sc7180/display/dsi_phy_pll.c A src/soc/qualcomm/sc7180/include/soc/display/display_resources.h A src/soc/qualcomm/sc7180/include/soc/display/dsi_phy.h A src/soc/qualcomm/sc7180/include/soc/display/dsi_phy_pll.h A src/soc/qualcomm/sc7180/include/soc/display/msm_panel.h A src/soc/qualcomm/sc7180/include/soc/display/panel.h A src/soc/qualcomm/sc7180/include/soc/mdss_6_2_0.h 8 files changed, 3,159 insertions(+), 0 deletions(-) git pull ssh://review.coreboot.org:29418/coreboot refs/changes/13/39613/1 diff --git a/src/soc/qualcomm/sc7180/display/dsi_phy.c b/src/soc/qualcomm/sc7180/display/dsi_phy.c new file mode 100644 index 0000000..5e12235 --- /dev/null +++ b/src/soc/qualcomm/sc7180/display/dsi_phy.c @@ -0,0 +1,1146 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2020 Qualcomm Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include <arch/mmio.h> +#include <lib.h> +#include <stdlib.h> +#include <console/console.h> +#include <delay.h> +#include <string.h> +#include <stdint.h> +#include <sys/types.h> +#include <soc/clock.h> +#include <soc/mdss_6_2_0.h> +#include <soc/display/dsi_phy.h> +#include <soc/display/display_resources.h> + +#define HAL_DSI_PHY_PLL_READY_TIMEOUT 150 /* ~15 ms */ +#define HAL_DSI_PHY_REFGEN_TIMEOUT 150 /* ~15 ms */ + +#define DSI_MAX_REFRESH_RATE 95 +#define DSI_MIN_REFRESH_RATE 15 + +#define HAL_DSI_PLL_VCO_MIN_MHZ_2_2_0 1000 + +typedef int32_t SIM_FLOAT; +typedef int32_t SIM_DOUBLE; + +typedef struct _dsi_phy_dividerlutentrytype_ { + uint16_t pll_post_div; + uint16_t phy_post_div; +} dsi_phy_dividerlutentrytype; + +/* PLL divider LUTs */ +static dsi_phy_dividerlutentrytype pll_dividerlut_dphy[] = { + { 2, 11}, + { 4, 5 }, + { 2, 9 }, + { 8, 2 }, + { 1, 15}, + { 2, 7 }, + { 1, 13}, + { 4, 3 }, + { 1, 11}, + { 2, 5 }, + { 1, 9 }, + { 8, 1 }, + { 1, 7 }, + { 2, 3 }, + { 1, 5 }, + { 4, 1 }, + { 1, 3 }, + { 2, 1 }, + { 1, 1 } +}; + +typedef enum { + DSI_DeviceID_0 = 0, + DSI_DeviceID_1, + DSI_DeviceID_MAX, + DSI_DeviceID_FORCE_32BIT = 0x7FFFFFFF +} dsi_devid_type; + +typedef struct _dsi_phy_laneconfig_type { + uint32_t data_strength_lp_P; + uint32_t data_strength_lp_N; + uint32_t data_strength_hs; + uint32_t clk_strength_hs; + uint32_t pemph_bottom; /* Determines how many pre-emphasis branches for bottom termination */ + uint32_t pemph_top; /* Determines how many pre-emphasis branches for top termination */ + bool pemph_enable; /* Enable driver pre-emphasis */ + bool strength_override; /* Strength override to use DSIPHY_LNn_TEST_STR */ +} dsi_phy_laneconfig_type; + +typedef enum { + DSI_LaneID_0 = 0, + DSI_LaneID_1, + DSI_LaneID_2, + DSI_LaneID_3, + DSI_LaneID_CLK, + DSI_LaneID_Max, + DSI_LaneID_FORCE_32BIT = 0x7FFFFFFF +} dsi_laneid_type; + + +typedef enum _dsi_pllconfig_sourcetype { + DSI_PLL_CONFIG_INDEPENDENT_SOURCE, /* PLL0 and PLL1 run independently */ + DSI_PLL_CONFIG_SPLIT_SOURCE, /* PLL0 is used to drive DSI0 and DSI1 */ + DSI_PLL_CONFIG_EXTERNAL_SOURCE, /* PLLs are used to drive external device */ +} dsi_pllconfig_sourcetype; + +typedef struct _dsi_phy_pllconfigtype { + uint32_t decdiv_start; /* Freq divider Decimal value */ + uint32_t fracdiv_low; /* Freq divider Fractional part bits 7:0 */ + uint32_t fracdiv_mid; /* Freq divider Fractional part bits 15:8 */ + uint32_t fracdiv_high; /* Freq divider Fractional part bits 17:16 */ + uint32_t pll_post_div; /* PLL Post divider ratio */ + uint32_t propgain_rate; + uint32_t lockdet_rate; + uint32_t freqdet_thresh; + uint32_t freqdet_refclk; + uint32_t freqdet_pllclk; + uint32_t sscper; + uint32_t ssc_adjper; + uint32_t ssc_stepsize; + uint32_t lock_delay; + uint32_t clock_inverters; + SIM_FLOAT pll_error_ppm; +} dsi_phy_pllconfigtype; + +typedef struct _dsi_phy_config_type { + dsi_devid_type dev_id; /* DSI Core ID */ + uint32_t desired_bitclk_freq; /* desired bit clock frequency in Hz */ + uint32_t bits_per_pixel; /* number of bits per pixel */ + uint32_t num_data_lanes; /* number of DSI data lanes */ + uint32_t cfg_flags; + /* PLL config options */ + bool dcdc_mode; /* Regulator mode, TRUE=DCDC ,FALSE=LDO */ + uint32_t clk_strength_hs; /* Clock lane strength in HS */ + uint32_t data_strength_hs; /* Data lane strength in HS */ + uint32_t data_strength_lp; /* Data lane strength in LP */ + dsi_pllconfig_sourcetype pll_config_source; /* PLL Source */ + uint32_t escape_freq; /* Escape clk freq in Hz */ + bool cphy_mode; /* C-Phy */ + uint32_t dsi_clksel; /* pixel clk source select */ + uint32_t phy_post_div; + uint32_t pll_post_div; +} dsi_phy_configtype; + +typedef struct _dsi_phy_configtype_info { + uint32_t pll_vco_output_freq; /* PLL VCO output frequency in Hz */ + uint32_t bitclk_freq; /* bit clock frequency in Hz */ + uint32_t byteclk_freq; /* byte clock frequency in Hz */ + uint32_t dsiclk_freq; /* DSI pclk clock frequency Hz */ + uint32_t pclk_freq; /* PClk frequency in Hz */ + uint32_t pclk_divnumerator; /* numerator of PClk divider ratio */ + uint32_t pclk_divdenominator; /* denominator of PClk divider ratio */ +} dsi_phy_configinfo_type; + +void mdss_dsi_phy_reset(uint32_t base); + +void mdss_dsi_phy_commit_pll(uint32_t dev_id, + dsi_pllconfig_sourcetype pll_cfg_source, + dsi_phy_pllconfigtype *pll_cfg); + +int32_t mdss_dsi_phy_timings(uint32_t dev_id, struct mipi_panel_info *mipi); + +uint32_t dsi_getregbase_offset(uint32_t dev_id); + +uint32_t dsi_phy_dsiclk_divider(dsi_phy_configtype *phy_cfg, + dsi_phy_configinfo_type *phy_cfg_info); + +void dsi_phy_mnd_divider(dsi_phy_configtype *phy_cfg, + dsi_phy_configinfo_type *phy_cfg_info); + +void dsi_phy_dsiclk_sel(dsi_phy_configtype *phy_cfg, + dsi_phy_configinfo_type *phy_cfg_info); + +static void dsi_phy_pll_set_source(dsi_phy_configtype *phy_cfg); + +int32_t mdss_dsi_phy_commit(uint32_t dev_id, dsi_phy_laneconfig_type lane_cfg, + struct mipi_panel_info *mipi); + +int dsi_phy_pll_calcandcommit(dsi_phy_configtype *phy_cfg, + dsi_phy_configinfo_type *phy_cfg_info); + +unsigned long dsi_phy_calc_clk_divider(dsi_phy_configtype *phy_cfg, + dsi_phy_pllconfigtype *pll_cfg, + dsi_phy_configinfo_type *phy_cfg_info); + +int mdss_dsi_phy_setup(struct mipi_panel_info *mipi); + +int32_t mdss_dsi_phy_setup_lanephy(uint32_t dev_id, dsi_laneid_type lane, + dsi_phy_laneconfig_type lane_cfg, + struct mipi_panel_info *mipi); + +uint32_t dsi_phy_getlane_offset(dsi_laneid_type laneId); + +int32_t mdss_dsi_power_down(uint32_t dev_id, struct mipi_panel_info *mipi); + +int mdss_dsi_phy_pll_setup(struct msm_panel_info *pinfo); + +uint32_t dsi_calc_desired_bitclk(struct msm_panel_info *pinfo); + +void dsi_phy_pll_outputdiv_rate(uint32_t id, dsi_phy_pllconfigtype *pll_cfg); + +int enable_dsi_clk(void); + +static uint32_t dsi_phy_rounddown(SIM_DOUBLE SIM_FLOAT_value) +{ + uint32_t roundupValue; + + if (SIM_FLOAT_value > 0) + roundupValue = (uint32_t)SIM_FLOAT_value; + else + roundupValue = 0; + + return roundupValue; +} + +void mdss_dsi_phy_commit_pll(uint32_t dev_id, + dsi_pllconfig_sourcetype pll_cfg_source, + dsi_phy_pllconfigtype *pll_cfg) +{ + uint32_t offset = dsi_getregbase_offset(dev_id); + uint32_t reg_val = 0; + uint32_t pll_post_div = 0; + uint32_t i = 0; + + /* PLL core input override */ + writel(offset + DSI_0_PHY_PLL_CORE_INPUT_OVERRIDE_ADDR, 0x12); + writel(0x12, offset + DSI_0_PHY_PLL_CORE_INPUT_OVERRIDE_ADDR); + + /* Dec div start */ + writel(pll_cfg->decdiv_start, + offset + DSI_0_PHY_PLL_DECIMAL_DIV_START_1_ADDR); + + /* Frac div low part */ + writel(pll_cfg->fracdiv_low, + offset + DSI_0_PHY_PLL_FRAC_DIV_START_LOW_1_ADDR); + + /* Frac div mid part */ + writel(pll_cfg->fracdiv_mid, + offset + DSI_0_PHY_PLL_FRAC_DIV_START_MID_1_ADDR); + + /* Frac div high part */ + writel(pll_cfg->fracdiv_high, + offset + DSI_0_PHY_PLL_FRAC_DIV_START_HIGH_1_ADDR); + + writel(pll_cfg->propgain_rate, + offset + DSI_0_PHY_PLL_PROP_GAIN_RATE_1_ADDR); + + /* Set BIAS_EN_MUX, BIAS_EN */ + reg_val = (1 << 6) | (1 << 7); + /* pll system muxes */ + writel(reg_val, offset + DSI_0_PHY_PLL_SYSTEM_MUXES_ADDR); + + /* lockdet */ + writel(pll_cfg->lockdet_rate, offset + DSI_0_PHY_PLL_LOCKDET_RATE_1_ADDR); + + /* Output divider */ + pll_post_div = 0; + + for (i = 0; i < 4; i++) { + if (pll_cfg->pll_post_div & (1 << i)) { + pll_post_div = i; + break; + } + } + reg_val = 0; + reg_val = pll_post_div & 0x3; + writel(reg_val, offset + DSI_0_PHY_PLL_OUTDIV_RATE_ADDR); + + /* Pll lock delay */ + writel(pll_cfg->lock_delay, offset + DSI_0_PHY_PLL_LOCK_DELAY_ADDR); + + /* clock inverters */ + writel(pll_cfg->clock_inverters, offset + DSI_0_PHY_PLL_CLOCK_INVERTERS_ADDR); + + //Step 3B + writel(0x00000010, offset + DSI_0_PHY_PLL_CMODE_ADDR); + + /* Frequency independent registers */ + writel(0x00000080, offset + DSI_0_PHY_PLL_ANALOG_CONTROLS_ONE_ADDR); + writel(0x00000003, offset + DSI_0_PHY_PLL_ANALOG_CONTROLS_TWO_ADDR); + writel(0x00000000, offset + DSI_0_PHY_PLL_ANALOG_CONTROLS_THREE_ADDR); + writel(0x00000000, offset + DSI_0_PHY_PLL_DSM_DIVIDER_ADDR); + writel(0x0000004E, offset + DSI_0_PHY_PLL_FEEDBACK_DIVIDER_ADDR); + writel(0x00000040, offset + DSI_0_PHY_PLL_CALIBRATION_SETTINGS_ADDR); + writel(0x000000BA, offset + DSI_0_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE_ADDR); + writel(0x0000000C, offset + DSI_0_PHY_PLL_FREQ_DETECT_SETTINGS_ONE_ADDR); + writel(0x00000000, offset + DSI_0_PHY_PLL_OUTDIV_ADDR); + writel(0x00000000, offset + DSI_0_PHY_PLL_CORE_OVERRIDE_ADDR); + writel(0x00000008, offset + DSI_1_PHY_PLL_DIGITAL_TIMERS_TWO_ADDR); + writel(0x000000C0, offset + DSI_0_PHY_PLL_BAND_SEL_RATE_1_ADDR); + writel(0x000000FA, offset + DSI_0_PHY_PLL_INT_GAIN_IFILT_BAND_1_ADDR); + writel(0x0000004C, offset + DSI_0_PHY_PLL_FL_INT_GAIN_PFILT_BAND_1_ADDR); + writel(0x00000080, offset + DSI_0_PHY_PLL_LOCK_OVERRIDE_ADDR); + writel(0x00000029, offset + DSI_0_PHY_PLL_PFILT_ADDR); + writel(0x0000003F, offset + DSI_0_PHY_PLL_IFILT_ADDR); + +} + +void mdss_dsi_phy_reset(uint32_t base) +{ + writel(0x40, (base + DSI_PHY_DSIPHY_CMN_CTRL_1_OFFSET)); + udelay(100); /*delay ~100us*/ + writel(0x0, (base + DSI_PHY_DSIPHY_CMN_CTRL_1_OFFSET)); +} + +uint32_t dsi_phy_getlane_offset(dsi_laneid_type laneId) +{ + uint32_t offset = 0; + + if (laneId == DSI_LaneID_0) + offset = 0; + else if (laneId == DSI_LaneID_1) + offset = DSI_0_PHY_DLN1_CFG0_ADDR - DSI_0_PHY_DLN0_CFG0_ADDR; + else if (laneId == DSI_LaneID_2) + offset = DSI_0_PHY_DLN2_CFG0_ADDR - DSI_0_PHY_DLN0_CFG0_ADDR; + else if (laneId == DSI_LaneID_3) + offset = DSI_0_PHY_DLN3_CFG0_ADDR - DSI_0_PHY_DLN0_CFG0_ADDR; + else if (laneId == DSI_LaneID_CLK) + offset = DSI_0_PHY_CKLN_CFG0_ADDR - DSI_0_PHY_DLN0_CFG0_ADDR; + else + offset = 0; + + return offset; +} + +uint32_t dsi_getregbase_offset(uint32_t dev_id) +{ + if (dev_id == 0) + return 0; + else if (dev_id == 1) + return (MIPI_DSI1_BASE - MIPI_DSI0_BASE); + else + return 0; //err +} + +int32_t mdss_dsi_power_down(uint32_t dev_id, struct mipi_panel_info *mipi) +{ + uint32_t offset = dsi_getregbase_offset(dev_id); + + /* power up DIGTOP & PLL */ + writel(0x00000060, offset + DSI_0_PHY_CMN_CTRL_0_ADDR); + + /* Disable PLL */ + writel(0x0, offset + DSI_0_PHY_CMN_PLL_CNTRL_ADDR); + + /* Resync re-time FIFO OFF*/ + writel(0x0, offset + DSI_0_PHY_CMN_RBUF_CTRL_ADDR); + + return NO_ERROR; +} + +int32_t mdss_dsi_phy_setup_lanephy(uint32_t dev_id, + dsi_laneid_type lane, + dsi_phy_laneconfig_type lane_cfg, + struct mipi_panel_info *mipi) +{ + int32_t ret = 0; + uint32_t reg_val = 0; + uint32_t offset = dsi_getregbase_offset(dev_id) + + dsi_phy_getlane_offset(lane); + uint32_t lprx_ctrl = 0; + uint32_t hstx_strength = 0; + uint32_t clk_lane = 0; + + if (DSI_LaneID_CLK == lane) { + clk_lane = 1; + hstx_strength = lane_cfg.clk_strength_hs; + } else { + clk_lane = 0; + hstx_strength = lane_cfg.data_strength_hs; + } + + if (DSI_LaneID_0 == lane) + lprx_ctrl = 3; + + // DSIPHY_STR_LP_N + // DSIPHY_STR_LP_P + reg_val = ((lane_cfg.data_strength_lp_N << 0x4) & 0xf0) | + (lane_cfg.data_strength_lp_P & 0x0f); + + writel(reg_val, offset + DSI_0_PHY_DLN0_LPTX_STR_CTRL_ADDR); + + /* DSIPHY_LPRX_EN */ + /* DSIPHY_CDRX_EN */ + /* Transition from 0 to 1 for DLN0-3 CLKLN stays 0 */ + writel(0x00000000, offset + DSI_0_PHY_DLN0_LPRX_CTRL_ADDR); + writel(lprx_ctrl, offset + DSI_0_PHY_DLN0_LPRX_CTRL_ADDR); + + /* Pin Swap */ + writel(0x00000000, offset + DSI_0_PHY_DLN0_PIN_SWAP_ADDR); + + /* DSIPHY_HSTX_STR_HSTOP */ + /* DSIPHY_HSTX_STR_HSBOT */ + writel(hstx_strength, offset + DSI_0_PHY_DLN0_HSTX_STR_CTRL_ADDR); + + /* PGM Delay */ + writel(0x00000000, offset + DSI_0_PHY_DLN0_CFG0_ADDR); + + /* DLN0_CFG1 */ + reg_val = lane_cfg.strength_override ? 1 : 0; + reg_val = (reg_val << 0x5) & 0x20; + writel(reg_val, offset + DSI_0_PHY_DLN0_CFG1_ADDR); + + /* DLN0_CFG2 */ + reg_val = ((lane_cfg.pemph_bottom << 0x04) & 0xf0) | + (lane_cfg.pemph_top & 0x0f); + + writel(reg_val, offset + DSI_0_PHY_DLN0_CFG2_ADDR); + + writel(0x00000000, offset + DSI_0_PHY_DLN0_OFFSET_TOP_CTRL_ADDR); + writel(0x00000000, offset + DSI_0_PHY_DLN0_OFFSET_BOT_CTRL_ADDR); + + /* DSIPHY_LPRX_DLY */ + /* IS_CKLANE */ + reg_val = (clk_lane << 0x07) & 0x80; + writel(reg_val, offset + DSI_0_PHY_DLN0_CFG3_ADDR); + + reg_val = 0; + + if (DSI_LaneID_CLK == lane) + reg_val = 1; + + if ((DSI_LaneID_3 == lane) && mipi->dual_dsi) + reg_val |= 0x04; + + writel(reg_val, offset + DSI_0_PHY_DLN0_TX_DCTRL_ADDR); + + return ret; +} + +int32_t mdss_dsi_phy_timings(uint32_t dev_id, struct mipi_panel_info *mipi) +{ + uint32_t reg_val = 0; + uint32_t offset = dsi_getregbase_offset(dev_id); + uint32_t *timing = mipi->mdss_dsi_phy_db->timing; + + if (mipi == NULL) { + printk(BIOS_ERR, "%s : mipi NULL, error\n", __func__); + return ERROR; + } + + // Step 4 Common block including GlobalTiming Parameters + /* BYTECLK_SEL */ + reg_val = (0x02 << 3) & 0x18; + + writel(reg_val, offset + DSI_0_PHY_CMN_GLBL_CTRL_ADDR); + + /* VREG_CTRL */ + writel(0x00000059, offset + DSI_0_PHY_CMN_VREG_CTRL_ADDR); + + /*HALFBYTECLK_EN*/ + writel(timing[0], offset + DSI_0_PHY_CMN_TIMING_CTRL_0_ADDR); + + /* T_CLK_ZERO */ + writel((uint32_t)mipi->mdss_dsi_phy_db->timing[1], offset + DSI_0_PHY_CMN_TIMING_CTRL_1_ADDR); + + /* T_CLK_PREPARE */ + writel((uint32_t)mipi->mdss_dsi_phy_db->timing[2], offset + DSI_0_PHY_CMN_TIMING_CTRL_2_ADDR); + + /* T_CLK_TRAIL */ + writel((uint32_t)mipi->mdss_dsi_phy_db->timing[3], offset + DSI_0_PHY_CMN_TIMING_CTRL_3_ADDR); + + /* T_HS_EXIT */ + writel((uint32_t)mipi->mdss_dsi_phy_db->timing[4], offset + DSI_0_PHY_CMN_TIMING_CTRL_4_ADDR); + + /* T_HS_ZERO */ + writel((uint32_t)mipi->mdss_dsi_phy_db->timing[5], offset + DSI_0_PHY_CMN_TIMING_CTRL_5_ADDR); + + /* T_HS_PREPARE */ + writel((uint32_t)mipi->mdss_dsi_phy_db->timing[6], offset + DSI_0_PHY_CMN_TIMING_CTRL_6_ADDR); + + /* T_HS_TRAIL */ + writel((uint32_t)mipi->mdss_dsi_phy_db->timing[7], offset + DSI_0_PHY_CMN_TIMING_CTRL_7_ADDR); + + /* T_HS_RQST */ + writel((uint32_t)mipi->mdss_dsi_phy_db->timing[8], offset + DSI_0_PHY_CMN_TIMING_CTRL_8_ADDR); + + /* T_TA_GO & T_TA_SURE */ + writel((uint32_t)mipi->mdss_dsi_phy_db->timing[9], offset + DSI_0_PHY_CMN_TIMING_CTRL_9_ADDR); + + /* T_TA_GET */ + writel((uint32_t)mipi->mdss_dsi_phy_db->timing[10], offset + DSI_0_PHY_CMN_TIMING_CTRL_10_ADDR); + + /*DSIPHY_TRIG3_CMD*/ + writel(0x00000000, offset + DSI_0_PHY_CMN_TIMING_CTRL_11_ADDR); + + /* DSI clock out timing ctrl T_CLK_PRE & T_CLK_POST*/ + reg_val = ((mipi->t_clk_post << 8) | mipi->t_clk_pre); + + writel(reg_val, offset + HWIO_DSI_0_CLKOUT_TIMING_CTRL_ADDR); + + /* DCTRL */ + writel(0x00000040, offset + DSI_0_PHY_CMN_CTRL_2_ADDR); + + return NO_ERROR; +} + +static int dsi_phy_waitforrefgen(dsi_devid_type dev_id) +{ + + uint32_t offset = dsi_getregbase_offset(dev_id); + uint32_t timeout = HAL_DSI_PHY_REFGEN_TIMEOUT; + uint32_t refgen = 0; + int ret = 0; + + while (refgen == 0) { + refgen = (readl(offset + DSI_0_PHY_CMN_PHY_STATUS_ADDR) & 0x1); + + if (refgen == 0) { + udelay(100); /*delay ~100us*/ + timeout--; + + if (timeout == 0) { + /* timeout while polling the lock status */ + ret = -1; + break; + } + } + } + + return ret; +} + +int32_t mdss_dsi_phy_commit(uint32_t dev_id, dsi_phy_laneconfig_type lane_cfg, + struct mipi_panel_info *mipi) +{ + uint32_t offset = dsi_getregbase_offset(dev_id); + int32_t ret = NO_ERROR; + + if (mipi == NULL) { + printk(BIOS_ERR, "%s: mipi NULL, error\n", __func__); + return ERROR; + } + + ret = dsi_phy_waitforrefgen(dev_id); + + if (ret != 0) { + printk(BIOS_ERR, "%s: waitforrefgen error\n", __func__); + return ret; + } + + mdss_dsi_power_down(dev_id, mipi); + + /* Remove PLL, DIG and all lanes from pwrdn */ + writel(0x0000007F, offset + DSI_0_PHY_CMN_CTRL_0_ADDR); + + /* Lane enable */ + writel(0x0000001F, offset + DSI_0_PHY_CMN_DSI_LANE_CTRL0_ADDR); + + mdss_dsi_phy_setup_lanephy(dev_id, DSI_LaneID_0, lane_cfg, mipi); + mdss_dsi_phy_setup_lanephy(dev_id, DSI_LaneID_1, lane_cfg, mipi); + mdss_dsi_phy_setup_lanephy(dev_id, DSI_LaneID_2, lane_cfg, mipi); + mdss_dsi_phy_setup_lanephy(dev_id, DSI_LaneID_3, lane_cfg, mipi); + mdss_dsi_phy_setup_lanephy(dev_id, DSI_LaneID_CLK, lane_cfg, mipi); + + return ret; +} + +int mdss_dsi_phy_setup(struct mipi_panel_info *mipi) +{ + dsi_phy_laneconfig_type lane_cfg; + + if (mipi == NULL) { + printk(BIOS_ERR, "%s: mipi is NULL, error\n", __func__); + return ERROR; + } + + /* Lane Settings */ + lane_cfg.data_strength_lp_N = 0x5; + lane_cfg.data_strength_lp_P = 0x5; + lane_cfg.data_strength_hs = 0x88; + lane_cfg.clk_strength_hs = 0x88; + lane_cfg.pemph_bottom = 0; + lane_cfg.pemph_top = 0; + lane_cfg.pemph_enable = false; + lane_cfg.strength_override = 0; + + //First reset phy + mdss_dsi_phy_reset(mipi->phy_base); + + if (mipi->dual_dsi) + mdss_dsi_phy_reset(mipi->sphy_base); + + //commit phy settings + mdss_dsi_phy_commit(0, lane_cfg, mipi); + + if (mipi->dual_dsi) + mdss_dsi_phy_commit(1, lane_cfg, mipi); + + return NO_ERROR; +} + +static void dsi_phy_resync_fifo(dsi_devid_type dev_id) +{ + uint32_t offset = dsi_getregbase_offset(dev_id); + + /* Resync FIFO*/ + writel(0x00000001, offset + DSI_0_PHY_CMN_RBUF_CTRL_ADDR); +} + +static void dsi_phy_pll_global_clk_enable(dsi_devid_type dev_id, bool enable) +{ + uint32_t offset = dsi_getregbase_offset(dev_id); + uint32_t clk_cfg = readl(offset + DSI_0_PHY_CMN_CLK_CFG1_ADDR); + uint32_t clk_enable = 0; + + /* Set CLK_EN */ + if (enable) + clk_enable = 1; + + clk_cfg &= ~0x20; + clk_cfg |= ((clk_enable << 0x5) & 0x20); + + /* clk cfg1 */ + writel(clk_cfg, offset + DSI_0_PHY_CMN_CLK_CFG1_ADDR); +} + +static int dsi_phy_pll_lock_detect(dsi_devid_type dev_id) +{ + int ret = 0; + uint32_t offset = dsi_getregbase_offset(dev_id); + uint32_t time_out = HAL_DSI_PHY_PLL_READY_TIMEOUT; + uint32_t pll_status; + + wmb(); /* ensure dsiclk_sel is always programmed before pll start */ + + /* Enable PLL */ + writel(0x1, offset + DSI_0_PHY_CMN_PLL_CNTRL_ADDR); + + /* + * ensure all PLL configurations are written prior to checking + * for PLL lock. + */ + wmb(); + + /* Wait for Lock */ + pll_status = readl(offset + DSI_0_PHY_PLL_COMMON_STATUS_ONE_ADDR) & 0x1; + + while ((pll_status == 0) && (time_out)) { + udelay(100); /*delay ~100us*/ + pll_status = readl(offset + DSI_0_PHY_PLL_COMMON_STATUS_ONE_ADDR)& 0x1; + time_out--; + } + + if ((pll_status & 0x1) == 0) { + /* timeout while polling the lock status */ + ret = -1; + printk(BIOS_ERR, "dsi pll lock detect timedout, error.\n"); + } + return ret; +} + +static void dsi_phy_toggle_dln3_tx_dctrl(dsi_devid_type dev_id) +{ + uint32_t offset = dsi_getregbase_offset(dev_id) + dsi_phy_getlane_offset(DSI_LaneID_3); + uint32_t reg_val = 0; + + reg_val = readl(offset + DSI_0_PHY_DLN0_TX_DCTRL_ADDR); + + /* clear bit 0 and keep all other bits including bit 2 */ + reg_val &= ~0x01; + + /* toggle bit 0 */ + writel((0x01 | reg_val), offset + DSI_0_PHY_DLN0_TX_DCTRL_ADDR); + writel(0x4, offset + DSI_0_PHY_DLN0_TX_DCTRL_ADDR); +} + +static void dsi_phy_pll_set_source(dsi_phy_configtype *phy_cfg) +{ + uint32_t offset = dsi_getregbase_offset(phy_cfg->dev_id); + uint32_t clk_cfg = readl(offset + DSI_0_PHY_CMN_CLK_CFG1_ADDR); + + if ((phy_cfg->pll_config_source == DSI_PLL_CONFIG_SPLIT_SOURCE) && + (phy_cfg->dev_id == DSI_DeviceID_1)) { + clk_cfg &= ~0x0c; + clk_cfg |= (((0x01) << 0x02) & 0x0c); + } else { + clk_cfg &= ~0x03; + clk_cfg |= ((phy_cfg->dsi_clksel) & 0x3); + } + + /* clk cfg1 */ + writel(clk_cfg, offset + DSI_0_PHY_CMN_CLK_CFG1_ADDR); +} + +static void dsi_phy_pll_bias_enable(dsi_devid_type dev_id, bool enable) +{ + uint32_t offset = dsi_getregbase_offset(dev_id); + uint32_t reg_val = 0; + + /* Set BIAS_EN_MUX, BIAS_EN */ + if (enable) + reg_val = (0x01 << 6) | (0x01 << 7); + + /* pll system muxes */ + writel(reg_val, offset + DSI_0_PHY_PLL_SYSTEM_MUXES_ADDR); + +} + +void dsi_phy_dsiclk_sel(dsi_phy_configtype *phy_cfg, + dsi_phy_configinfo_type *phy_cfg_info) +{ + uint32_t dsi_clk_sel = 0; + + /* C-phy */ + if (phy_cfg->cphy_mode) + printk(BIOS_ERR, "C Phy not supported, error\n"); + else /* D-Phy */ + dsi_clk_sel = 1; + + phy_cfg->dsi_clksel = dsi_clk_sel; +} + +void dsi_phy_mnd_divider(dsi_phy_configtype *phy_cfg, + dsi_phy_configinfo_type *phy_cfg_info) +{ + uint32_t m_val = 1; + uint32_t n_val = 1; + + if (phy_cfg->cphy_mode) { /* C-phy */ + printk(BIOS_ERR, "C Phy not supported, error\n"); + } else { /* D-Phy */ + if (phy_cfg->bits_per_pixel == 18) { + switch (phy_cfg->num_data_lanes) { + case 1: + case 2: + m_val = 2; + n_val = 9; + break; + case 4: + m_val = 4; + n_val = 9; + break; + default: + break; + } + } else if ((phy_cfg->bits_per_pixel == 16) && + (phy_cfg->num_data_lanes == 3)) { + m_val = 3; + n_val = 8; + } else if ((phy_cfg->bits_per_pixel == 30) && + (phy_cfg->num_data_lanes == 4)) { + m_val = 2; + n_val = 3; + } + } + + /*Save M/N info */ + phy_cfg_info->pclk_divnumerator = m_val; + phy_cfg_info->pclk_divdenominator = n_val; + +} + +uint32_t dsi_phy_dsiclk_divider(dsi_phy_configtype *phy_cfg, + dsi_phy_configinfo_type *phy_cfg_info) +{ + uint32_t m_val = phy_cfg_info->pclk_divnumerator; + uint32_t n_val = phy_cfg_info->pclk_divdenominator; + uint32_t div_ctrl = 0; + uint32_t fval; + + if (phy_cfg->cphy_mode) { /* C-phy */ + printk(BIOS_ERR, "C Phy unsupported, error\n"); + } else { + fval = (m_val * phy_cfg->bits_per_pixel) / + (n_val * phy_cfg->num_data_lanes * 2); + + if (phy_cfg->bits_per_pixel >= 16) + div_ctrl = (uint32_t)fval; + else + div_ctrl = dsi_phy_rounddown(fval); + + } + + return div_ctrl; +} + + +unsigned long dsi_phy_calc_clk_divider(dsi_phy_configtype *phy_cfg, + dsi_phy_pllconfigtype *pll_cfg, + dsi_phy_configinfo_type *phy_cfg_info) +{ + bool div_found = false; + uint32_t offset = dsi_getregbase_offset(phy_cfg->dev_id); + uint32_t m_val = 1; + uint32_t n_val = 1; + uint32_t div_ctrl = 0; + uint32_t reg_val = 0; + uint32_t pll_post_div = 0; + uint32_t phy_post_div = 0; + uint64_t vco_freq_hz = 0; + uint64_t fval = 0; + uint64_t pll_output_freq_hz; + uint64_t desired_bitclk_hz; + uint64_t min_vco_freq_hz = 0; //0.0f; + uint32_t lut_max; + int i; + dsi_phy_dividerlutentrytype *lut; + + /* Napali, use 1000Mhz */ + min_vco_freq_hz = (HAL_DSI_PLL_VCO_MIN_MHZ_2_2_0 * 1000000); + + dsi_phy_mnd_divider(phy_cfg, phy_cfg_info); + + m_val = phy_cfg_info->pclk_divnumerator; + n_val = phy_cfg_info->pclk_divdenominator; + + /* Desired clock in MHz */ + desired_bitclk_hz = (uint64_t)phy_cfg->desired_bitclk_freq; + + if (phy_cfg->cphy_mode) { + printk(BIOS_ERR, "cphy_mode is not supported, error.\n"); + goto out; + } else { + /* D Phy */ + lut = pll_dividerlut_dphy; + lut_max = sizeof(pll_dividerlut_dphy) / sizeof(*lut); + lut += (lut_max - 1); + } + + /* + * PLL Post Div - from LUT + * Check the LUT in reverse order + */ + for (i = lut_max - 1; i >= 0; i--, lut--) { + fval = (uint64_t)lut->phy_post_div * + (uint64_t)lut->pll_post_div; + + if (fval) { + if ((desired_bitclk_hz * fval) > min_vco_freq_hz) { + /* Range found */ + pll_post_div = lut->pll_post_div; + phy_post_div = lut->phy_post_div; + div_found = true; + break; + } + } + } + + if (div_found) { + pll_cfg->pll_post_div = pll_post_div; + phy_cfg->pll_post_div = pll_post_div; + phy_cfg->phy_post_div = phy_post_div; + + /* Div Ctrl*/ + dsi_phy_dsiclk_sel(phy_cfg, phy_cfg_info); + + /*div_ctrl_7_4 */ + div_ctrl = dsi_phy_dsiclk_divider(phy_cfg, phy_cfg_info); + + /* DIV_CTRL_7_4 DIV_CTRL_3_0 + (DIV_CTRL_3_0 = PHY post divider ratio) */ + reg_val = (div_ctrl << 0x04) & 0xf0; + + if ((phy_cfg->pll_config_source == DSI_PLL_CONFIG_SPLIT_SOURCE) + && (phy_cfg->dev_id == DSI_DeviceID_1)) { + /* For slave node PHY post div is forced to 1 */ + reg_val |= 0x01; + } else { + reg_val |= (phy_post_div & 0x0f); + } + + writel(reg_val, offset + DSI_0_PHY_CMN_CLK_CFG0_ADDR); + + /* PLL output frequency = desired_bitclk_hz * phy_post_div */ + pll_output_freq_hz = desired_bitclk_hz * phy_post_div; + + /* VCO output freq*/ + vco_freq_hz = pll_output_freq_hz * pll_post_div; + + } else { + printk(BIOS_ERR, "div not found, error\n"); + } +out: + return (unsigned long)vco_freq_hz; +} + +void dsi_phy_pll_outputdiv_rate(uint32_t dev_id, dsi_phy_pllconfigtype *pll_cfg) +{ + /* Output divider */ + uint32_t pll_post_div = 0; + uint32_t i = 0; + uint32_t reg_val = 0; + uint32_t offset = dsi_getregbase_offset(dev_id); + + for (i = 0; i < 4; i++) { + if (pll_cfg->pll_post_div & (1 << i)) { + pll_post_div = i; + break; + } + } + + reg_val = 0; + reg_val = pll_post_div & 0x3; + writel(reg_val, offset + DSI_0_PHY_PLL_OUTDIV_RATE_ADDR); +} + +int dsi_phy_pll_calcandcommit(dsi_phy_configtype *phy_cfg, + dsi_phy_configinfo_type *phy_cfg_info) +{ + + unsigned long vco_freq_hz; + dsi_phy_pllconfigtype pll_cfg; + dsi_devid_type dev_id = phy_cfg->dev_id; + int ret = 0; + + /* validate input parameters */ + if ((phy_cfg == NULL) || + (phy_cfg_info == NULL)) { + ret = -1; + goto out; + } + else if ((phy_cfg->dev_id != DSI_DeviceID_0) && + (phy_cfg->dev_id != DSI_DeviceID_1)) { + ret = -1; + goto out; + } + else if ((phy_cfg->bits_per_pixel != 16) && + (phy_cfg->bits_per_pixel != 18) && + (phy_cfg->bits_per_pixel != 24)) { + + /* Unsupported pixel bit depth */ + ret = -1; + goto out; + } + else if ((phy_cfg->num_data_lanes == 0) || + (phy_cfg->num_data_lanes > 4)) { + + /* Illegal number of DSI data lanes */ + ret = -1; + goto out; + } + + memset((void *)&pll_cfg, 0, sizeof(dsi_phy_pllconfigtype)); + + /* Save Clock info */ + phy_cfg_info->bitclk_freq = phy_cfg->desired_bitclk_freq; + printk(BIOS_INFO, "calc vco rate with desired_bitclk_freq: %u\n",phy_cfg_info->bitclk_freq); + + vco_freq_hz = dsi_phy_calc_clk_divider(phy_cfg, &pll_cfg, phy_cfg_info); + + if (vco_freq_hz == 0) { + /* bitclock too low - unsupported */ + printk(BIOS_ERR, "vco_freq_hz is 0, unsupported\n"); + ret = -1; + goto out; + } + + /* Enable PLL bias */ + dsi_phy_pll_bias_enable(phy_cfg->dev_id, true); + + /* Set byte clk source */ + dsi_phy_pll_set_source(phy_cfg); + + if ((phy_cfg->pll_config_source == DSI_PLL_CONFIG_SPLIT_SOURCE) && + (phy_cfg->dev_id == DSI_DeviceID_1)) { + /* Global clock enable */ + dsi_phy_pll_global_clk_enable(phy_cfg->dev_id, true); + + /* Resync FIFOs */ + dsi_phy_resync_fifo(dev_id); + } else { + dsi_phy_pll_outputdiv_rate(phy_cfg->dev_id, &pll_cfg); + dsi_phy_pll_vco_10nm_set_rate(phy_cfg->dev_id, vco_freq_hz); + + dsi_phy_toggle_dln3_tx_dctrl(dev_id); + + /* Steps 6,7 Start PLL & Lock */ + if (ret == 0) + ret = dsi_phy_pll_lock_detect(dev_id); + + /* Step 8 - Resync Data Paths */ + if (ret == 0) { + /* Global clock enable */ + dsi_phy_pll_global_clk_enable(phy_cfg->dev_id, true); + + /* Resync FIFOs */ + dsi_phy_resync_fifo(dev_id); + } + } + return 0; +out: + return ret; +} + +uint32_t dsi_calc_desired_bitclk(struct msm_panel_info *pinfo) +{ + uint64_t desired_bclk = 0; + uint32_t num_lines = pinfo->mipi.num_of_lanes; + uint32_t bpp = pinfo->bpp; + uint32_t width = pinfo->xres + pinfo->lcdc.h_back_porch + + pinfo->lcdc.h_front_porch + pinfo->lcdc.h_pulse_width; + uint32_t height = pinfo->yres + pinfo->lcdc.v_back_porch + + pinfo->lcdc.v_front_porch + pinfo->lcdc.v_pulse_width; + + /* If the upper layer has requested a specific bitclock frequency + * override the calculated bitclock frequency. + */ + if (pinfo->mipi.bitclock > 0) { + // Use the bitclock from the upper layer (in Hz) + desired_bclk = (uint64_t)(pinfo->mipi.bitclock); + printk(BIOS_INFO, "Override bitclock:%llu\n", desired_bclk); + } + else { + // refresh_rate is in Q16.16 format + uint32_t refresh_rate = pinfo->mipi.frame_rate; + + // Perform some sanity checking, clamp the refresh rate + // MAX/MIN refresh rate also defined as Q16.16 format + if (refresh_rate > DSI_MAX_REFRESH_RATE) + refresh_rate = DSI_MAX_REFRESH_RATE; + else if (refresh_rate < DSI_MIN_REFRESH_RATE) + refresh_rate = DSI_MIN_REFRESH_RATE; + + if (num_lines) { + desired_bclk = (uint64_t)(height)*(uint64_t)(width); + desired_bclk = desired_bclk * (uint64_t)refresh_rate; + desired_bclk = desired_bclk * (uint64_t)bpp; + desired_bclk = desired_bclk/(uint64_t)(num_lines); + } + + } + + printk(BIOS_INFO, "Desired bitclock:%u\n", (uint32_t)desired_bclk); + return (uint32_t)desired_bclk; +} + +int mdss_dsi_phy_pll_setup(struct msm_panel_info *pinfo) +{ + dsi_phy_configtype phy_cfg; + dsi_phy_configinfo_type phy_cfgtype; + int ret = NO_ERROR; + + /* Setup the PhyStructure */ + memset(&phy_cfg, 0, sizeof(dsi_phy_configtype)); + memset(&phy_cfgtype, 0, sizeof(dsi_phy_configinfo_type)); + + phy_cfg.dev_id = DSI_DeviceID_0; + phy_cfg.bits_per_pixel = pinfo->bpp; //bits_per_pixel; + phy_cfg.num_data_lanes = pinfo->mipi.num_of_lanes; //uNumLanes; + phy_cfg.cfg_flags = 0; + + /* desired DSI PLL bit clk freq in Hz */ + phy_cfg.desired_bitclk_freq = dsi_calc_desired_bitclk(pinfo); + phy_cfg.escape_freq = 19; + phy_cfg.cphy_mode = false; + + if (pinfo->mipi.dual_dsi) + phy_cfg.pll_config_source = DSI_PLL_CONFIG_SPLIT_SOURCE; + else + phy_cfg.pll_config_source = DSI_PLL_CONFIG_INDEPENDENT_SOURCE; + + ret = dsi_phy_pll_calcandcommit(&phy_cfg, &phy_cfgtype); + + if (ret) + goto out; + + ret = mdss_dsi_phy_timings(DSI_DeviceID_0, &(pinfo->mipi)); + if (ret) + goto out; + + if (pinfo->mipi.dual_dsi) { + phy_cfg.dev_id = DSI_DeviceID_1; + ret = dsi_phy_pll_calcandcommit(&phy_cfg, &phy_cfgtype); + + if (ret) + goto out; + + ret = mdss_dsi_phy_timings(DSI_DeviceID_1, &(pinfo->mipi)); + + if (ret) + goto out; + } +out: + return ret; +} + +int enable_dsi_clk(void) +{ + int ret = 0; + uint32_t clk_enable = 1; + MDPExternalClockEntry *clk_list = sDSI0ExtClocks_6xx; + + if(clk_list != NULL){ + uint32_t i = 0; + + while (clk_list[i].szName[0] != '\0') { + //Set Ext Source + ret = mdss_clock_configure(clk_list[i].szName, + clk_list[i].uClkSource, + clk_list[i].nClkDiv, + clk_list[i].uClkPLL_M, + clk_list[i].uClkPLL_N, + clk_list[i].uClkPLL_2D); + + if (ret != 0) { + printk(BIOS_ERR,"mdss_clock_configure fialed for %s\n",clk_list[i].szName); + goto out; + } + + ret = mdss_clock_enable(clk_list[i].szName, clk_enable); + + if (ret != 0) { + printk(BIOS_ERR,"mdss_clock_enable fialed for %s\n",clk_list[i].szName); + goto out; + } + + i++; + } + } +out: + return ret; +} + +int mdss_dsi_phy_10nm_init(struct msm_panel_info *pinfo) +{ + int ret = NO_ERROR; + + if (pinfo == NULL) { + printk(BIOS_ERR, "%s: pinfo NULL, error\n", __func__); + goto out; + } + + //Phy set up + ret = mdss_dsi_phy_setup(&(pinfo->mipi)); + + if (ret) + goto out; + + ret = mdss_dsi_phy_pll_setup(pinfo); + + enable_dsi_clk(); + +out: + return ret; +} + +int mdss_dsi_phy_intf_setup(uint32_t phy_pll_type, mdss_dsi_phy_ftable *intf) +{ + int32_t ret = -1; + + if (intf != NULL && phy_pll_type == DSI_PLL_TYPE_10NM) { + memset(intf, 0, sizeof(intf)); + intf->dsi_phy_init = mdss_dsi_phy_10nm_init; + return 0; + } + + return ret; +} + diff --git a/src/soc/qualcomm/sc7180/display/dsi_phy_pll.c b/src/soc/qualcomm/sc7180/display/dsi_phy_pll.c new file mode 100644 index 0000000..c54668f --- /dev/null +++ b/src/soc/qualcomm/sc7180/display/dsi_phy_pll.c @@ -0,0 +1,475 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2020 Qualcomm Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#include <arch/mmio.h> +#include <lib.h> +#include <stdlib.h> +#include <console/console.h> +#include <delay.h> +#include <device/device.h> +#include <edid.h> +#include <types.h> +#include <string.h> + +#include <soc/mdss_6_2_0.h> +#include <soc/display/dsi_phy_pll.h> + +#define DSI_0_PHY_PLL_QLINK_COM_REG_BASE (MDSSHW_BASE + 0x00094a00) +#define VCO_DELAY_USEC 1 + +#define MHZ_250 250000000UL +#define MHZ_500 500000000UL +#define MHZ_1000 1000000000UL +#define MHZ_1100 1100000000UL +#define MHZ_1900 1900000000UL +#define MHZ_3000 3000000000UL + +/* Register Offsets from PLL base address */ +#define PLL_ANALOG_CONTROLS_ONE 0x000 +#define PLL_ANALOG_CONTROLS_TWO 0x004 +#define PLL_INT_LOOP_SETTINGS 0x008 +#define PLL_INT_LOOP_SETTINGS_TWO 0x00c +#define PLL_ANALOG_CONTROLS_THREE 0x010 +#define PLL_ANALOG_CONTROLS_FOUR 0x014 +#define PLL_INT_LOOP_CONTROLS 0x018 +#define PLL_DSM_DIVIDER 0x01c +#define PLL_FEEDBACK_DIVIDER 0x020 +#define PLL_SYSTEM_MUXER 0x024 +#define PLL_FREQ_UPDATE_CONTROL_OVERRIDES 0x028 +#define PLL_CMODE 0x02c +#define PLL_CALIBRATION_SETTINGS 0x030 +#define PLL_BAND_SEL_CAL_TIMER_LOW 0x034 +#define PLL_BAND_SEL_CAL_TIMER_HIGH 0x038 +#define PLL_BAND_SEL_CAL_SETTINGS 0x03c +#define PLL_BAND_SEL_MIN 0x040 +#define PLL_BAND_SEL_MAX 0x044 +#define PLL_BAND_SEL_PFILT 0x048 +#define PLL_BAND_SEL_IFILT 0x04c +#define PLL_BAND_SEL_CAL_SETTINGS_TWO 0x050 +#define PLL_BAND_SEL_CAL_SETTINGS_THREE 0x054 +#define PLL_BAND_SEL_CAL_SETTINGS_FOUR 0x058 +#define PLL_BAND_SEL_ICODE_HIGH 0x05c +#define PLL_BAND_SEL_ICODE_LOW 0x060 +#define PLL_FREQ_DETECT_SETTINGS_ONE 0x064 +#define PLL_PFILT 0x07c +#define PLL_IFILT 0x080 +#define PLL_GAIN 0x084 +#define PLL_ICODE_LOW 0x088 +#define PLL_ICODE_HIGH 0x08c +#define PLL_LOCKDET 0x090 +#define PLL_OUTDIV 0x094 +#define PLL_FASTLOCK_CONTROL 0x098 +#define PLL_PASS_OUT_OVERRIDE_ONE 0x09c +#define PLL_PASS_OUT_OVERRIDE_TWO 0x0a0 +#define PLL_CORE_OVERRIDE 0x0a4 +#define PLL_CORE_INPUT_OVERRIDE 0x0a8 +#define PLL_RATE_CHANGE 0x0ac +#define PLL_PLL_DIGITAL_TIMERS 0x0b0 +#define PLL_PLL_DIGITAL_TIMERS_TWO 0x0b4 +#define PLL_DEC_FRAC_MUXES 0x0c8 +#define PLL_DECIMAL_DIV_START_1 0x0cc +#define PLL_FRAC_DIV_START_LOW_1 0x0d0 +#define PLL_FRAC_DIV_START_MID_1 0x0d4 +#define PLL_FRAC_DIV_START_HIGH_1 0x0d8 +#define PLL_MASH_CONTROL 0x0ec +#define PLL_SSC_MUX_CONTROL 0x108 +#define PLL_SSC_STEPSIZE_LOW_1 0x10c +#define PLL_SSC_STEPSIZE_HIGH_1 0x110 +#define PLL_SSC_DIV_PER_LOW_1 0x114 +#define PLL_SSC_DIV_PER_HIGH_1 0x118 +#define PLL_SSC_DIV_ADJPER_LOW_1 0x11c +#define PLL_SSC_DIV_ADJPER_HIGH_1 0x120 +#define PLL_SSC_CONTROL 0x13c +#define PLL_PLL_OUTDIV_RATE 0x140 +#define PLL_PLL_LOCKDET_RATE_1 0x144 +#define PLL_PLL_PROP_GAIN_RATE_1 0x14c +#define PLL_PLL_BAND_SET_RATE_1 0x154 +#define PLL_PLL_INT_GAIN_IFILT_BAND_1 0x15c +#define PLL_PLL_FL_INT_GAIN_PFILT_BAND_1 0x164 +#define PLL_FASTLOCK_EN_BAND 0x16c +#define PLL_FREQ_TUNE_ACCUM_INIT_MUX 0x17c +#define PLL_PLL_LOCK_OVERRIDE 0x180 +#define PLL_PLL_LOCK_DELAY 0x184 +#define PLL_PLL_LOCK_MIN_DELAY 0x188 +#define PLL_CLOCK_INVERTERS 0x18c +#define PLL_SPARE_AND_JPC_OVERRIDES 0x190 +#define PLL_BIAS_CONTROL_1 0x194 +#define PLL_BIAS_CONTROL_2 0x198 +#define PLL_ALOG_OBSV_BUS_CTRL_1 0x19c +#define PLL_COMMON_STATUS_ONE 0x1a0 + +/* Register Offsets from PHY base address */ +#define PHY_CMN_CLK_CFG0 0x010 +#define PHY_CMN_CLK_CFG1 0x014 +#define PHY_CMN_RBUF_CTRL 0x01c +#define PHY_CMN_PLL_CNTRL 0x038 +#define PHY_CMN_CTRL_0 0x024 + +# define do_div(n, base) ( \ +{ \ + uint32_t __base = (base); \ + uint32_t __rem; \ + __rem = ((uint64_t)(n)) % __base; \ + (n) = ((uint64_t)(n)) / __base; \ + __rem; \ +} \ +) \ + +#define DIV_ROUND_CLOSEST_ULL(x, divisor)( \ +{ \ + typeof(divisor) __d = divisor; \ + unsigned long long _tmp = (x) + (__d) / 2; \ + do_div(_tmp, __d); \ + _tmp; \ +} \ +) + +/* Bit definition of SSC control registers */ +#define SSC_CENTER BIT(0) +#define SSC_EN BIT(1) +#define SSC_FREQ_UPDATE BIT(2) +#define SSC_FREQ_UPDATE_MUX BIT(3) +#define SSC_UPDATE_SSC BIT(4) +#define SSC_UPDATE_SSC_MUX BIT(5) +#define SSC_START BIT(6) +#define SSC_START_MUX BIT(7) + +enum { + DSI_PLL_0, + DSI_PLL_1, + DSI_PLL_MAX +}; + +struct dsi_pll_regs { + u32 pll_prop_gain_rate; + u32 pll_lockdet_rate; + u32 decimal_div_start; + u32 frac_div_start_low; + u32 frac_div_start_mid; + u32 frac_div_start_high; + u32 pll_clock_inverters; + u32 ssc_stepsize_low; + u32 ssc_stepsize_high; + u32 ssc_div_per_low; + u32 ssc_div_per_high; + u32 ssc_adjper_low; + u32 ssc_adjper_high; + u32 ssc_control; +}; + +struct dsi_pll_config { + u32 ref_freq; + bool div_override; + u32 output_div; + bool ignore_frac; + bool disable_prescaler; + bool enable_ssc; + bool ssc_center; + u32 dec_bits; + u32 frac_bits; + u32 lock_timer; + u32 ssc_freq; + u32 ssc_offset; + u32 ssc_adj_per; + u32 thresh_cycles; + u32 refclk_cycles; +}; + +struct dsi_pll_10nm { + struct mdss_pll_resources *rsc; + struct dsi_pll_config pll_configuration; + struct dsi_pll_regs reg_setup; +}; + +static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) +{ + *remainder = dividend % divisor; + return dividend / divisor; +} + +static inline u64 div_u64(u64 dividend, u32 divisor) +{ + u32 remainder; + return div_u64_rem(dividend, divisor, &remainder); +} + +static struct dsi_pll_10nm plls[DSI_PLL_MAX]; + +static void dsi_pll_setup_config(struct dsi_pll_10nm *pll, + struct mdss_pll_resources *rsc) +{ + struct dsi_pll_config *config = &pll->pll_configuration; + config->ref_freq = 19200000; + config->output_div = 1; + config->dec_bits = 8; + config->frac_bits = 18; + config->lock_timer = 64; + config->ssc_freq = 31500; + config->ssc_offset = 5000; + config->ssc_adj_per = 2; + config->thresh_cycles = 32; + config->refclk_cycles = 256; + + config->div_override = false; + config->ignore_frac = false; + config->disable_prescaler = false; + config->enable_ssc = rsc->ssc_en; + config->ssc_center = rsc->ssc_center; + + if (config->enable_ssc) { + + if (rsc->ssc_freq) + config->ssc_freq = rsc->ssc_freq; + + if (rsc->ssc_ppm) + config->ssc_offset = rsc->ssc_ppm; + } +} + +static void dsi_pll_init_val(struct mdss_pll_resources *rsc) +{ + void *pll_base = rsc->pll_base; + + MDSS_PLL_REG_W(pll_base, PLL_CORE_INPUT_OVERRIDE, 0x10); + MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_SETTINGS, 0x3f); + MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_SETTINGS_TWO, 0x0); + MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_FOUR, 0x0); + MDSS_PLL_REG_W(pll_base, PLL_INT_LOOP_CONTROLS, 0x80); + MDSS_PLL_REG_W(pll_base, PLL_FREQ_UPDATE_CONTROL_OVERRIDES, 0x0); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_TIMER_LOW, 0x0); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_TIMER_HIGH, 0x02); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS, 0x82); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_MIN, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_MAX, 0xff); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_PFILT, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_IFILT, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_TWO, 0x25); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_FOUR, 0x4f); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_ICODE_HIGH, 0x0a); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_ICODE_LOW, 0x0); + MDSS_PLL_REG_W(pll_base, PLL_GAIN, 0x42); + MDSS_PLL_REG_W(pll_base, PLL_ICODE_LOW, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_ICODE_HIGH, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_LOCKDET, 0x30); + MDSS_PLL_REG_W(pll_base, PLL_FASTLOCK_CONTROL, 0x04); + MDSS_PLL_REG_W(pll_base, PLL_PASS_OUT_OVERRIDE_ONE, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_PASS_OUT_OVERRIDE_TWO, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_RATE_CHANGE, 0x01); + MDSS_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS, 0x08); + MDSS_PLL_REG_W(pll_base, PLL_DEC_FRAC_MUXES, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_MASH_CONTROL, 0x03); + MDSS_PLL_REG_W(pll_base, PLL_SSC_MUX_CONTROL, 0x0); + MDSS_PLL_REG_W(pll_base, PLL_SSC_CONTROL, 0x0); + MDSS_PLL_REG_W(pll_base, PLL_FASTLOCK_EN_BAND, 0x03); + MDSS_PLL_REG_W(pll_base, PLL_FREQ_TUNE_ACCUM_INIT_MUX, 0x0); + MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_MIN_DELAY, 0x19); + MDSS_PLL_REG_W(pll_base, PLL_SPARE_AND_JPC_OVERRIDES, 0x0); + MDSS_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_1, 0x40); + MDSS_PLL_REG_W(pll_base, PLL_BIAS_CONTROL_2, 0x20); + MDSS_PLL_REG_W(pll_base, PLL_ALOG_OBSV_BUS_CTRL_1, 0x0); +} + +static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll, + struct mdss_pll_resources *rsc) +{ + struct dsi_pll_config *config = &pll->pll_configuration; + struct dsi_pll_regs *regs = &pll->reg_setup; + u64 fref = rsc->vco_ref_clk_rate; + u64 pll_freq; + u64 divider; + u64 dec, dec_multiple; + u32 frac; + u64 multiplier; + + pll_freq = rsc->vco_current_rate; + + if (config->disable_prescaler) + divider = fref; + else + divider = fref * 2; + + multiplier = 1 << config->frac_bits; + dec_multiple = div_u64(pll_freq * multiplier, divider); + div_u64_rem(dec_multiple, multiplier, &frac); + + dec = div_u64(dec_multiple, multiplier); + + if (pll_freq <= MHZ_1900) + regs->pll_prop_gain_rate = 8; + else if (pll_freq <= MHZ_3000) + regs->pll_prop_gain_rate = 10; + else + regs->pll_prop_gain_rate = 12; + + if (pll_freq < MHZ_1100) + regs->pll_clock_inverters = 8; + else + regs->pll_clock_inverters = 0; + + regs->pll_lockdet_rate = config->lock_timer; + regs->decimal_div_start = dec; + regs->frac_div_start_low = (frac & 0xff); + regs->frac_div_start_mid = (frac & 0xff00) >> 8; + regs->frac_div_start_high = (frac & 0x30000) >> 16; +} + +static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll, + struct mdss_pll_resources *rsc) +{ + struct dsi_pll_config *config = &pll->pll_configuration; + struct dsi_pll_regs *regs = &pll->reg_setup; + u32 ssc_per; + u32 ssc_mod; + u64 ssc_step_size; + u64 frac; + + if (!config->enable_ssc) { + printk(BIOS_INFO, "SSC not enabled\n"); + return; + } + + ssc_per = DIV_ROUND_CLOSEST(config->ref_freq, config->ssc_freq) / 2 - 1; + ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1); + ssc_per -= ssc_mod; + + frac = regs->frac_div_start_low | + (regs->frac_div_start_mid << 8) | + (regs->frac_div_start_high << 16); + + ssc_step_size = regs->decimal_div_start; + ssc_step_size *= (1 << config->frac_bits); + ssc_step_size += frac; + ssc_step_size *= config->ssc_offset; + ssc_step_size *= (config->ssc_adj_per + 1); + ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1)); + ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000); + + regs->ssc_div_per_low = ssc_per & 0xFF; + regs->ssc_div_per_high = (ssc_per & 0xFF00) >> 8; + regs->ssc_stepsize_low = (u32)(ssc_step_size & 0xFF); + regs->ssc_stepsize_high = (u32)((ssc_step_size & 0xFF00) >> 8); + regs->ssc_adjper_low = config->ssc_adj_per & 0xFF; + regs->ssc_adjper_high = (config->ssc_adj_per & 0xFF00) >> 8; + + regs->ssc_control = config->ssc_center ? SSC_CENTER : 0; + + printk(BIOS_INFO, "SCC: Dec:%d, frac:%llu, frac_bits:%d\n", + regs->decimal_div_start, frac, config->frac_bits); + + printk(BIOS_INFO, "SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n", + ssc_per, (u32)ssc_step_size, config->ssc_adj_per); +} + +static void dsi_pll_commit(struct dsi_pll_10nm *pll, + struct mdss_pll_resources *rsc) +{ + void *pll_base = rsc->pll_base; + struct dsi_pll_regs *reg = &pll->reg_setup; + + MDSS_PLL_REG_W(pll_base, PLL_CORE_INPUT_OVERRIDE, 0x12); + MDSS_PLL_REG_W(pll_base, PLL_DECIMAL_DIV_START_1,reg->decimal_div_start); + MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_LOW_1,reg->frac_div_start_low); + MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_MID_1,reg->frac_div_start_mid); + MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_HIGH_1,reg->frac_div_start_high); + MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_1, 0x40); + MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_DELAY, 0x06); + MDSS_PLL_REG_W(pll_base, PLL_CMODE, 0x10); + MDSS_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS, reg->pll_clock_inverters); +} + +static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll, + struct mdss_pll_resources *rsc) +{ + void *pll_base = rsc->pll_base; + + MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_ONE, 0x80); + MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_TWO, 0x03); + MDSS_PLL_REG_W(pll_base, PLL_ANALOG_CONTROLS_THREE, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_DSM_DIVIDER, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_FEEDBACK_DIVIDER, 0x4e); + MDSS_PLL_REG_W(pll_base, PLL_CALIBRATION_SETTINGS, 0x40); + MDSS_PLL_REG_W(pll_base, PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba); + MDSS_PLL_REG_W(pll_base, PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c); + MDSS_PLL_REG_W(pll_base, PLL_OUTDIV, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_CORE_OVERRIDE, 0x00); + MDSS_PLL_REG_W(pll_base, PLL_PLL_DIGITAL_TIMERS_TWO, 0x08); + MDSS_PLL_REG_W(pll_base, PLL_PLL_PROP_GAIN_RATE_1, 0x08); + MDSS_PLL_REG_W(pll_base, PLL_PLL_BAND_SET_RATE_1, 0xc0); + MDSS_PLL_REG_W(pll_base, PLL_PLL_INT_GAIN_IFILT_BAND_1, 0xfa); + MDSS_PLL_REG_W(pll_base, PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c); + MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_OVERRIDE, 0x80); + MDSS_PLL_REG_W(pll_base, PLL_PFILT, 0x29); + MDSS_PLL_REG_W(pll_base, PLL_IFILT, 0x3f); +} + +static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll, + struct mdss_pll_resources *rsc) +{ + void *pll_base = rsc->pll_base; + struct dsi_pll_regs *regs = &pll->reg_setup; + + if (pll->pll_configuration.enable_ssc) { + printk(BIOS_INFO, "SSC is enabled\n"); + + MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_LOW_1,regs->ssc_stepsize_low); + MDSS_PLL_REG_W(pll_base, PLL_SSC_STEPSIZE_HIGH_1,regs->ssc_stepsize_high); + MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_LOW_1,regs->ssc_div_per_low); + MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_PER_HIGH_1,regs->ssc_div_per_high); + MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_ADJPER_LOW_1,regs->ssc_adjper_low); + MDSS_PLL_REG_W(pll_base, PLL_SSC_DIV_ADJPER_HIGH_1,regs->ssc_adjper_high); + MDSS_PLL_REG_W(pll_base, PLL_SSC_CONTROL,SSC_EN | regs->ssc_control); + } +} + +/* +static int vco_10nm_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +*/ +int dsi_phy_pll_vco_10nm_set_rate(int idx, unsigned long rate) +{ + int rc = NO_ERROR; + struct mdss_pll_resources rsc; + struct dsi_pll_10nm *pll; + + memset((void *)&rsc, 0, sizeof(struct mdss_pll_resources)); + rsc.pll_base = (void *)DSI_0_PHY_PLL_QLINK_COM_REG_BASE; + rsc.ssc_en = false; + + rsc.priv = &plls[idx]; + pll = (struct dsi_pll_10nm *)rsc.priv; + + rsc.vco_current_rate = rate; + rsc.vco_ref_clk_rate = 19200000UL; + + dsi_pll_init_val(&rsc); + + dsi_pll_setup_config(pll, &rsc); + + dsi_pll_calc_dec_frac(pll, &rsc); + + dsi_pll_calc_ssc(pll, &rsc); + + dsi_pll_commit(pll, &rsc); + + dsi_pll_config_hzindep_reg(pll, &rsc); + + dsi_pll_ssc_commit(pll, &rsc); + + /* flush, ensure all register writes are done*/ + wmb(); + + return rc; +} + diff --git a/src/soc/qualcomm/sc7180/include/soc/display/display_resources.h b/src/soc/qualcomm/sc7180/include/soc/display/display_resources.h new file mode 100644 index 0000000..4e71297 --- /dev/null +++ b/src/soc/qualcomm/sc7180/include/soc/display/display_resources.h @@ -0,0 +1,49 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2018 Qualcomm Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _PLATFORM_DISPLAY_RESOURCES_H_ +#define _PLATFORM_DISPLAY_RESOURCES_H_ + +#define MDP_MAX_CLOCK_NAME 30 + +static char esc0_clk_name[MDP_MAX_CLOCK_NAME] = "disp_cc_mdss_esc0_clk"; +static char pclk0_clk_name[MDP_MAX_CLOCK_NAME] = "disp_cc_mdss_pclk0_clk"; +static char byte0_clk_name[MDP_MAX_CLOCK_NAME] = "disp_cc_mdss_byte0_clk"; +static char byte0_intf_clk_name[MDP_MAX_CLOCK_NAME] = "disp_cc_mdss_byte0_intf_clk"; +static char clk_null[MDP_MAX_CLOCK_NAME] = "\0"; + +/* MDP External Clocks Entry + */ +typedef struct { + char *szName; /* Clock name */ + uint32_t uClkSource; /* Primary Clock Source */ + uint32_t uClkSecondarySource; /* Secondary Clock source */ + uint32_t nClkDiv; /* Clock pre-divider */ + uint32_t uClkPLL_M; /* Clock M value */ + uint32_t uClkPLL_N; /* Clock N value */ + uint32_t uClkPLL_2D; /* Clock 2D value */ + uint32_t nSourceDiv; /* Clock may need source divider */ +} MDPExternalClockEntry; + +MDPExternalClockEntry sDSI0ExtClocks_6xx[] = { + {esc0_clk_name, 0, 1, 0, 0, 0, 0}, + {pclk0_clk_name, 1, 0, 0, 0, 0, 0}, + {byte0_clk_name, 1, 0, 0, 0, 0, 0}, + {byte0_intf_clk_name,1, 0, 2, 0, 0, 0, 2}, + {clk_null, 0, 0, 0, 0, 0, 0}, +}; + +#endif + diff --git a/src/soc/qualcomm/sc7180/include/soc/display/dsi_phy.h b/src/soc/qualcomm/sc7180/include/soc/display/dsi_phy.h new file mode 100644 index 0000000..2449023 --- /dev/null +++ b/src/soc/qualcomm/sc7180/include/soc/display/dsi_phy.h @@ -0,0 +1,67 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2018 Qualcomm Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DSI_PHY_H +#define _DSI_PHY_H + +#include <soc/display/dsi_phy_pll.h> + +#define MAX_REGULATOR_CONFIG 7 +#define MAX_BIST_CONFIG 6 +#define MAX_TIMING_CONFIG 40 +#define MAX_LANE_CONFIG 45 +#define MAX_STRENGTH_CONFIG 10 +#define MAX_CTRL_CONFIG 4 +#define DMA_TPG_FIFO_LEN 64 + +struct msm_panel_info; +struct mipi_dsi_phy_ctrl { + uint32_t regulator[5]; + uint32_t timing[12]; + uint32_t ctrl[4]; + uint32_t strength[4]; + uint32_t pll[21]; +}; + +enum dsi_reg_mode { + DSI_PHY_REGULATOR_DCDC_MODE, + DSI_PHY_REGULATOR_LDO_MODE, +}; + +enum { + DSI_PLL_TYPE_10NM, + DSI_PLL_TYPE_MAX, +}; + +struct mdss_dsi_phy_ctrl { + uint32_t regulator[MAX_REGULATOR_CONFIG]; + uint32_t timing[MAX_TIMING_CONFIG]; + uint32_t ctrl[MAX_CTRL_CONFIG]; + uint32_t strength[MAX_STRENGTH_CONFIG]; + char bistCtrl[MAX_BIST_CONFIG]; + char laneCfg[MAX_LANE_CONFIG]; + enum dsi_reg_mode regulator_mode; + int pll_type; +}; + +typedef struct _mdss_dsi_phy_ftable { + int (*dsi_phy_init)(struct msm_panel_info *pinfo); +} mdss_dsi_phy_ftable; + +int mdss_dsi_phy_intf_setup(uint32_t phy_pll_type, mdss_dsi_phy_ftable *ftable); +int mdss_dsi_phy_10nm_init(struct msm_panel_info *pinfo); + +#endif + diff --git a/src/soc/qualcomm/sc7180/include/soc/display/dsi_phy_pll.h b/src/soc/qualcomm/sc7180/include/soc/display/dsi_phy_pll.h new file mode 100644 index 0000000..be2d06c --- /dev/null +++ b/src/soc/qualcomm/sc7180/include/soc/display/dsi_phy_pll.h @@ -0,0 +1,169 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2018 Qualcomm Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __DSI_PHY_PLL_H +#define __DSI_PHY_PLL_H + +#define MDSS_PLL_REG_W(base, offset, data) \ + write32(((base) + (offset)), (data)) +#define MDSS_PLL_REG_R(base, offset) read32((base) + (offset)) + +#define PLL_CALC_DATA(addr0, addr1, data0, data1) \ + (((data1) << 24) | ((((addr1) / 4) & 0xFF) << 16) | \ + ((data0) << 8) | (((addr0) / 4) & 0xFF)) + +#define MDSS_DYN_PLL_REG_W(base, offset, addr0, addr1, data0, data1) \ + writel_relaxed(((base) + (offset)), \ + PLL_CALC_DATA(addr0, addr1, data0, data1)) + +enum { + MDSS_DSI_PLL_10NM, + MDSS_DP_PLL_10NM, + MDSS_UNKNOWN_PLL, +}; + +enum { + MDSS_PLL_TARGET_8996, +}; + +struct mdss_pll_resources { + + /* Pll specific resources like GPIO, power supply, clocks, etc*/ + + /* + * dsi/edp/hmdi plls' base register, phy, gdsc and dynamic refresh + * register mapping + */ + void *pll_base; + void *phy_base; + void *ln_tx0_base; + void *ln_tx1_base; + void *gdsc_base; + void *dyn_pll_base; + + bool is_init_locked; + s64 vco_current_rate; + s64 vco_locking_rate; + s64 vco_ref_clk_rate; + + /* + * Certain pll's needs to update the same vco rate after resume in + * suspend/resume scenario. Cached the vco rate for such plls. + */ + unsigned long vco_cached_rate; + u32 cached_cfg0; + u32 cached_cfg1; + u32 cached_outdiv; + + /* dsi/edp/hmdi pll interface type */ + u32 pll_interface_type; + + /* + * Target ID. Used in pll_register API for valid target check before + * registering the PLL clocks. + */ + u32 target_id; + + /* HW recommended delay during configuration of vco clock rate */ + u32 vco_delay; + + /* Ref-count of the PLL resources */ + u32 resource_ref_cnt; + + /* + * Keep track to resource status to avoid updating same status for the + * pll from different paths + */ + bool resource_enable; + + /* + * Certain plls' do not allow vco rate update if it is on. Keep track of + * status for them to turn on/off after set rate success. + */ + bool pll_on; + + /* + * handoff_status is true of pll is already enabled by bootloader with + * continuous splash enable case. Clock API will call the handoff API + * to enable the status. It is disabled if continuous splash + * feature is disabled. + */ + bool handoff_resources; + + /* + * caching the pll trim codes in the case of dynamic refresh + */ + int cache_pll_trim_codes[2]; + + /* + * for maintaining the status of saving trim codes + */ + bool reg_upd; + + /* + * PLL index if multiple index are available. Eg. in case of + * DSI we have 2 plls. + */ + uint32_t index; + + bool ssc_en; /* share pll with master */ + bool ssc_center; /* default is down spread */ + u32 ssc_freq; + u32 ssc_ppm; + + struct mdss_pll_resources *slave; + + /* + * target pll revision information + */ + int revision; + + void *priv; + + /* + * dynamic refresh pll codes stored in this structure + */ + struct dfps_info *dfps; + +}; + +struct mdss_pll_vco_calc { + s32 div_frac_start1; + s32 div_frac_start2; + s32 div_frac_start3; + s64 dec_start1; + s64 dec_start2; + s64 pll_plllock_cmp1; + s64 pll_plllock_cmp2; + s64 pll_plllock_cmp3; +}; + +static inline int mdss_set_mux_sel(void *context, unsigned int reg, + unsigned int val) +{ + return 0; +} + +static inline int mdss_get_mux_sel(void *context, unsigned int reg, + unsigned int *val) +{ + *val = 0; + return 0; +} + +int dsi_phy_pll_vco_10nm_set_rate(int dev_id, unsigned long rate); + +#endif + diff --git a/src/soc/qualcomm/sc7180/include/soc/display/msm_panel.h b/src/soc/qualcomm/sc7180/include/soc/display/msm_panel.h new file mode 100644 index 0000000..37758d4 --- /dev/null +++ b/src/soc/qualcomm/sc7180/include/soc/display/msm_panel.h @@ -0,0 +1,324 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2018 Qualcomm Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _PLATFORM_MSM_PANEL_H_ +#define _PLATFORM_MSM_PANEL_H_ + +#include <sys/types.h> +#include <stdint.h> +#include <sys/types.h> +#include <soc/display/dsi_phy.h> + +#define DFPS_MAX_FRAME_RATE 20 +#define DFPS_PLL_CODES_SIZE 0x1000 /* One page */ +#define NO_ERROR 0 +#define ERROR -1 + +#define NO_PANEL 0xffff +#define MIPI_VIDEO_PANEL 8 +#define MIPI_CMD_PANEL 9 +#define DISPLAY_UNKNOWN 0 +#define DISPLAY_1 1 +#define DISPLAY_2 2 + +struct fbcon_config { + void *base; + unsigned int width; + unsigned int height; + unsigned int stride; + unsigned int bpp; + unsigned int sbpp; + unsigned int format; +}; + +enum mdss_mdp_pipe_type { + MDSS_MDP_PIPE_TYPE_VIG, + MDSS_MDP_PIPE_TYPE_RGB, + MDSS_MDP_PIPE_TYPE_DMA, +}; + +struct lcdc_panel_info { + uint32_t h_back_porch; + uint32_t h_front_porch; + uint32_t h_pulse_width; + uint32_t v_back_porch; + uint32_t v_front_porch; + uint32_t v_pulse_width; + uint32_t border_clr; + uint32_t underflow_clr; + uint32_t hsync_skew; + uint32_t xres_pad; + uint32_t yres_pad; + uint8_t dual_pipe; + uint8_t split_display; + uint8_t pipe_swap; + uint8_t dst_split; +}; + +enum { + COMPRESSION_NONE, + COMPRESSION_DSC, + COMPRESSION_FBC +}; + +#define DCS_HDR_LEN 4 +#define DSC_PPS_LEN 128 + +struct msm_panel_info; + +struct dsc_desc { + int initial_lines; + int slice_last_group_size; + int bpp; /* target bit per pixel */ + int bpc; /* bit per component */ + int line_buf_depth; + int config_by_manufacture_cmd; + int block_pred_enable; + int vbr_enable; + int enable_422; + int convert_rgb; + int input_10_bits; + int slice_per_pkt; + + int major; + int minor; + int scr_rev; + int pps_id; + + int pic_height; + int pic_width; + int slice_height; + int slice_width; + int chunk_size; + + int pkt_per_line; + int bytes_in_slice; + int bytes_per_pkt; + int eol_byte_num; + int pclk_per_line; /* width */ + + int initial_dec_delay; + int initial_xmit_delay; + + int initial_scale_value; + int scale_decrement_interval; + int scale_increment_interval; + + int first_line_bpg_offset; + int nfl_bpg_offset; + int slice_bpg_offset; + + int initial_offset; + int final_offset; + + int rc_model_size; /* rate_buffer_size */ + + int det_thresh_flatness; + int max_qp_flatness; + int min_qp_flatness; + int edge_factor; + int quant_incr_limit0; + int quant_incr_limit1; + int tgt_offset_hi; + int tgt_offset_lo; + char *buf_thresh; + char *range_min_qp; + char *range_max_qp; + char *range_bpg_offset; + char pps_buf[DCS_HDR_LEN + DSC_PPS_LEN]; + + void (*parameter_calc)(struct msm_panel_info *pinfo); + int (*dsc2buf)(struct msm_panel_info *pinfo); + void (*dsi_dsc_config)(uint32_t base, int mode, struct dsc_desc *dsc); + void (*mdp_dsc_config)(struct msm_panel_info *pinfo, + unsigned int pp_base, unsigned int dsc_base, + bool mux, bool split_mode); +}; + +struct dfps_panel_info { + uint32_t enabled; + uint32_t frame_rate_cnt; + uint32_t frame_rate[DFPS_MAX_FRAME_RATE]; +}; + +struct dfps_pll_codes { + uint32_t codes[2]; +}; + +struct dfps_codes_info { + uint32_t is_valid; + uint32_t frame_rate; + uint32_t clk_rate; + struct dfps_pll_codes pll_codes; +}; + +struct dfps_info { + struct dfps_panel_info panel_dfps; + struct dfps_codes_info codes_dfps[DFPS_MAX_FRAME_RATE]; + void *dfps_fb_base; + uint32_t chip_serial; +}; + +/* intf timing settings */ +struct intf_timing_params { + uint32_t width; + uint32_t height; + uint32_t xres; + uint32_t yres; + + uint32_t h_back_porch; + uint32_t h_front_porch; + uint32_t v_back_porch; + uint32_t v_front_porch; + uint32_t hsync_pulse_width; + uint32_t vsync_pulse_width; + + uint32_t border_clr; + uint32_t underflow_clr; + uint32_t hsync_skew; +}; + +struct mipi_panel_info { + char cmds_post_tg; /* send on commands after tg on */ + char mode; /* video/cmd */ + char interleave_mode; + int eof_bllp_power; + uint32_t bitclock; + char crc_check; + char ecc_check; + char dst_format; /* shared by video and command */ + char num_of_lanes; + char data_lane0; + char data_lane1; + char data_lane2; + char data_lane3; + char dlane_swap; /* data lane swap */ + char rgb_swap; + char b_sel; + char g_sel; + char r_sel; + char rx_eot_ignore; + char tx_eot_append; + char t_clk_post; /* 0xc0, DSI_CLKOUT_TIMING_CTRL */ + char t_clk_pre; /* 0xc0, DSI_CLKOUT_TIMING_CTRL */ + char vc; /* virtual channel */ + struct mipi_dsi_phy_ctrl *dsi_phy_db; + struct mdss_dsi_phy_ctrl *mdss_dsi_phy_db; + struct mipi_dsi_cmd *panel_on_cmds; + int num_of_panel_on_cmds; + struct mipi_dsi_cmd *panel_off_cmds; + int num_of_panel_off_cmds; + /* video mode */ + char pulse_mode_hsa_he; + char hfp_power_stop; + char hbp_power_stop; + char hsa_power_stop; + char eof_bllp_power_stop; + char bllp_power_stop; + char traffic_mode; + char frame_rate; + /* command mode */ + char interleave_max; + char insert_dcs_cmd; + char wr_mem_continue; + char wr_mem_start; + char te_sel; + char stream; /* 0 or 1 */ + char mdp_trigger; + char dma_trigger; + uint32_t dsi_pclk_rate; + /* The packet-size should not bet changed */ + char no_max_pkt_size; + /* Clock required during LP commands */ + char force_clk_lane_hs; + char lane_swap; + uint8_t dual_dsi; + uint8_t use_dsi1_pll; + uint8_t broadcast; + uint8_t mode_gpio_state; + uint32_t signature; + uint32_t use_enable_gpio; + uint32_t ctl_base; + uint32_t phy_base; + uint32_t sctl_base; + uint32_t sphy_base; + uint32_t reg_base; + uint32_t sreg_base; + uint32_t pll_base; + uint32_t spll_base; + + struct dfps_pll_codes pll_codes; +}; + +struct msm_panel_info { + uint32_t xres; + uint32_t yres; + uint32_t bpp; + uint32_t type; + uint32_t wait_cycle; + uint32_t clk_rate; + uint32_t orientation; + uint32_t dest; + uint32_t compression_mode; + /* Select pipe type for handoff */ + uint32_t pipe_type; + char lowpowerstop; + char lcd_reg_en; + uint32_t border_top; + uint32_t border_bottom; + uint32_t border_left; + uint32_t border_right; + + int lm_split[2]; + int num_dsc_enc; + + struct lcdc_panel_info lcdc; + struct dsc_desc dsc; + struct mipi_panel_info mipi; + bool has_bridge_chip; + struct dfps_info dfps; + + int (*on)(void); + int (*off)(void); + int (*pre_on)(void); + int (*pre_off)(void); + int (*prepare)(void); + int (*early_config)(void *pdata); + int (*config)(void *pdata); + int (*rotate)(void); + + char autorefresh_enable; + uint32_t autorefresh_framenum; +}; + +struct msm_fb_panel_data { + struct msm_panel_info panel_info; + struct fbcon_config fb; + int mdp_rev; + int rotate; + + /* function entry chain */ + int (*power_func)(uint8_t enable, struct msm_panel_info *pinfo); + uint32_t (*clk_func)(uint8_t enable, struct msm_panel_info *pinfo); + int (*bl_func)(uint8_t enable); + uint32_t (*pll_clk_func)(uint8_t enable, struct msm_panel_info *pinfo); + int (*dfps_func)(struct msm_panel_info *pinfo); + int (*post_power_func)(int enable); + int (*pre_init_func)(void); + int (*update_panel_info)(void); +}; + +#endif + diff --git a/src/soc/qualcomm/sc7180/include/soc/display/panel.h b/src/soc/qualcomm/sc7180/include/soc/display/panel.h new file mode 100644 index 0000000..afd701f --- /dev/null +++ b/src/soc/qualcomm/sc7180/include/soc/display/panel.h @@ -0,0 +1,189 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2020 Qualcomm Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _PANEL_H_ +#define _PANEL_H_ + +/*---------------------------------------------------------------------------*/ +/* HEADER files */ +/*---------------------------------------------------------------------------*/ +#include <types.h> + +#define TOTAL_RESET_GPIO_CTRL 5 + +/*---------------------------------------------------------------------------*/ +/* panel type */ +/*---------------------------------------------------------------------------*/ +enum { + PANEL_TYPE_UNKNOWN, + PANEL_TYPE_DSI, +}; + +/*---------------------------------------------------------------------------*/ +/* Structure definition */ +/*---------------------------------------------------------------------------*/ + +/*Panel Configuration */ +struct panel_config { + char *panel_node_id; + char *panel_controller; + char *panel_compatible; + uint16_t panel_interface; + uint16_t panel_type; + char *panel_destination; + uint32_t panel_orientation; + uint32_t panel_clockrate; /* panel_clockrate is deprecated in favor of panel_bitclock_freq */ + uint16_t panel_framerate; + uint16_t panel_channelid; + uint16_t dsi_virtualchannel_id; + uint16_t panel_broadcast_mode; + uint16_t panel_lp11_init; + uint16_t panel_init_delay; + uint16_t dsi_stream; + uint8_t interleave_mode; + uint32_t panel_bitclock_freq; + uint32_t panel_operating_mode; + uint32_t panel_with_enable_gpio; + uint8_t mode_gpio_state; + char *slave_panel_node_id; +}; + +struct panel_resolution { + uint16_t panel_width; + uint16_t panel_height; + uint16_t hfront_porch; + uint16_t hback_porch; + uint16_t hpulse_width; + uint16_t hsync_skew; + uint16_t vfront_porch; + uint16_t vback_porch; + uint16_t vpulse_width; + uint16_t hleft_border; + uint16_t hright_border; + uint16_t vtop_border; + uint16_t vbottom_border; + uint16_t hactive_res; + uint16_t vactive_res; + uint16_t invert_data_polarity; + uint16_t invert_vsync_polarity; + uint16_t invert_hsync_polarity; +}; + +struct color_info { + uint8_t color_format; + uint8_t color_order; + uint8_t underflow_color; + uint8_t border_color; + uint8_t pixel_packing; + uint8_t pixel_alignment; +}; + +struct command_state { + uint8_t oncommand_state; + uint8_t offcommand_state; +}; + +struct videopanel_info { + uint8_t hsync_pulse; + uint8_t hfp_power_mode; + uint8_t hbp_power_mode; + uint8_t hsa_power_mode; + uint8_t bllp_eof_power_mode; + uint8_t bllp_power_mode; + uint8_t traffic_mode; + uint8_t dma_delayafter_vsync; + uint32_t bllp_eof_power; +}; + +struct commandpanel_info { + uint8_t techeck_enable; + uint8_t tepin_select; + uint8_t teusing_tepin; + uint8_t autorefresh_enable; + uint32_t autorefresh_framenumdiv; + uint32_t tevsync_rdptr_irqline; + uint32_t tevsync_continue_lines; + uint32_t tevsync_startline_divisor; + uint32_t tepercent_variance; + uint8_t tedcs_command; + uint8_t disable_eotafter_hsxfer; + uint32_t cmdmode_idletime; +}; + +struct lane_configuration { + uint8_t dsi_lanes; + uint8_t dsi_lanemap; + uint8_t lane0_state; + uint8_t lane1_state; + uint8_t lane2_state; + uint8_t lane3_state; + uint8_t force_clk_lane_hs; +}; + +struct panel_timing { + uint8_t dsi_mdp_trigger; + uint8_t dsi_dma_trigger; + uint8_t tclk_post; + uint8_t tclk_pre; +}; + +enum { + BL_PWM = 0, + BL_WLED, + BL_DCS, +}; + +struct panel_reset_sequence { + uint8_t pin_state[TOTAL_RESET_GPIO_CTRL]; + uint32_t sleep[TOTAL_RESET_GPIO_CTRL]; + uint8_t pin_direction; +}; + +struct backlight { + uint16_t bl_interface_type; + uint16_t bl_min_level; + uint16_t bl_max_level; + uint16_t bl_step; + uint16_t bl_pmic_controltype; + char *bl_pmic_model; +}; + +struct dsc_parameters { + uint32_t major; + uint32_t minor; + uint32_t pps_id; + uint32_t slice_height; + uint32_t slice_width; + uint32_t bpp; /* target bpp */ + uint32_t bpc; /* target bpc, byte per component */ + uint32_t slice_per_pkt; + uint32_t block_prediction; + uint32_t scr_rev; +}; + +struct topology_config { + char *config_name; /* matches with kernel cmdline */ + /* + * lm_split: -ve value means that lm_split is not used. + * If lm_split is used then DUAL_PIPE flag will be added. + */ + int lm_split[2]; + int num_dsc_enc; /* how many encoder to use */ + struct dsc_parameters *dsc; + int use_pingpong_split; +}; + +#endif /*_PANEL_H_ */ + diff --git a/src/soc/qualcomm/sc7180/include/soc/mdss_6_2_0.h b/src/soc/qualcomm/sc7180/include/soc/mdss_6_2_0.h new file mode 100644 index 0000000..ce7df01 --- /dev/null +++ b/src/soc/qualcomm/sc7180/include/soc/mdss_6_2_0.h @@ -0,0 +1,740 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2020, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MDSS_6_2_0_H_ +#define _MDSS_6_2_0_H_ + +#include <types.h> +#include <soc/display/msm_panel.h> + +#define writel(v, a) write32((void *)(size_t)(a), (v)) +#define readl(a) read32((void *)(size_t)(a)) + +/* + HWIO_OUT_FLD: macro to update a given field in a 32 bit value + regVal = current value of a register + io = name of register + field = field inside register + fldVal = value to insert in the given field + eg regVal = HWIO_OUT_FLD(regVal, HWIO_MDP_VP_0_VIG_0_SSPP_OUT_SIZE, DST_H,720); +*/ +#define HWIO_OUT_FLD(regVal, io, field, fldVal) (uint32_t)((((uint32_t)(fldVal) << HWIO_##io##_##field##_SHFT) & HWIO_##io##_##field##_BMSK) | ((uint32_t)(regVal) & ~ HWIO_##io##_##field##_BMSK)) + +#define FRAMEBUFFER_SRC_BPP 32 +#define MDSSHW_BASE (0x0AE00000) +#define MIPI_DSI_BASE (MDSSHW_BASE + 0x94000) +#define MIPI_DSI0_BASE (MIPI_DSI_BASE) +#define MIPI_DSI1_BASE (MDSSHW_BASE + 0x96000) +#define DSI0_PHY_BASE (MDSSHW_BASE + 0x94400) +#define DSI1_PHY_BASE (MDSSHW_BASE + 0x96400) +#define MDSS_VBIF_RT_BASE (MDSSHW_BASE + 0xB0000) +#define MMSS_DSI_PHY_PLL_CORE_VCO_TUNE 0x0D0 +#define MMSS_DSI_PHY_PLL_CORE_KVCO_CODE 0x0D4 + +#define REG_MDP(off) (MDSSHW_BASE + (off)) + +#ifdef MDP_PP_0_BASE +#undef MDP_PP_0_BASE +#endif +#define MDP_PP_0_BASE REG_MDP(0x71000) + +#ifdef MDP_PP_1_BASE +#undef MDP_PP_1_BASE +#endif +#define MDP_PP_1_BASE REG_MDP(0x71800) + +#ifdef MDP_DSC_0_BASE +#undef MDP_DSC_0_BASE +#endif +#define MDP_DSC_0_BASE REG_MDP(0x81000) + +#ifdef MDP_DSC_1_BASE +#undef MDP_DSC_1_BASE +#endif +#define MDP_DSC_1_BASE REG_MDP(0x81400) + +#ifdef MDP_HW_REV +#undef MDP_HW_REV +#endif +#define MDP_HW_REV REG_MDP(0x1000) + +#ifdef MDP_INTR_EN +#undef MDP_INTR_EN +#endif +#define MDP_INTR_EN REG_MDP(0x1010) + +#ifdef MDP_INTR_CLEAR +#undef MDP_INTR_CLEAR +#endif +#define MDP_INTR_CLEAR REG_MDP(0x1018) + +#ifdef MDP_HIST_INTR_EN +#undef MDP_HIST_INTR_EN +#endif +#define MDP_HIST_INTR_EN REG_MDP(0x101C) + +#ifdef MDP_VIDEO_INTF_UNDERFLOW_CTL +#undef MDP_VIDEO_INTF_UNDERFLOW_CTL +#endif +#define MDP_VIDEO_INTF_UNDERFLOW_CTL REG_MDP(0x12E0) + +#ifdef MDP_UPPER_NEW_ROI_PRIOR_RO_START +#undef MDP_UPPER_NEW_ROI_PRIOR_RO_START +#endif +#define MDP_UPPER_NEW_ROI_PRIOR_RO_START REG_MDP(0x11EC) + +#ifdef MDP_LOWER_NEW_ROI_PRIOR_TO_START +#undef MDP_LOWER_NEW_ROI_PRIOR_TO_START +#endif +#define MDP_LOWER_NEW_ROI_PRIOR_TO_START REG_MDP(0x13F8) + +#ifdef MDP_INTF_0_TIMING_ENGINE_EN +#undef MDP_INTF_0_TIMING_ENGINE_EN +#endif +#define MDP_INTF_0_TIMING_ENGINE_EN REG_MDP(0x6b000) + +#ifdef MDP_INTF_1_TIMING_ENGINE_EN +#undef MDP_INTF_1_TIMING_ENGINE_EN +#endif +#define MDP_INTF_1_TIMING_ENGINE_EN REG_MDP(0x6b800) + +#ifdef MDP_INTF_2_TIMING_ENGINE_EN +#undef MDP_INTF_2_TIMING_ENGINE_EN +#endif +#define MDP_INTF_2_TIMING_ENGINE_EN REG_MDP(0x6C000) + +#ifdef MDP_INTF_3_TIMING_ENGINE_EN +#undef MDP_INTF_3_TIMING_ENGINE_EN +#endif +#define MDP_INTF_3_TIMING_ENGINE_EN REG_MDP(0x6C800) + +#ifdef MDP_CTL_0_BASE +#undef MDP_CTL_0_BASE +#endif +#define MDP_CTL_0_BASE REG_MDP(0x2000) + +#ifdef MDP_CTL_1_BASE +#undef MDP_CTL_1_BASE +#endif +#define MDP_CTL_1_BASE REG_MDP(0x2200) + +#ifdef MDP_REG_SPLIT_DISPLAY_EN +#undef MDP_REG_SPLIT_DISPLAY_EN +#endif +#define MDP_REG_SPLIT_DISPLAY_EN REG_MDP(0x12F4) + +#ifdef MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL +#undef MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL +#endif +#define MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL REG_MDP(0x12F8) + +#ifdef MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL +#undef MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL +#endif +#define MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL REG_MDP(0x13F0) + +#ifdef MDP_INTF_0_BASE +#undef MDP_INTF_0_BASE +#endif +#define MDP_INTF_0_BASE REG_MDP(0x6b000) + +#ifdef MDP_INTF_1_BASE +#undef MDP_INTF_1_BASE +#endif +#define MDP_INTF_1_BASE REG_MDP(0x6b800) + +#ifdef MDP_INTF_2_BASE +#undef MDP_INTF_2_BASE +#endif +#define MDP_INTF_2_BASE REG_MDP(0x6c000) + +#ifdef MDP_INTF_3_BASE +#undef MDP_INTF_3_BASE +#endif +#define MDP_INTF_3_BASE REG_MDP(0x6c800) + +#ifdef MDP_CLK_CTRL0 +#undef MDP_CLK_CTRL0 +#endif +#define MDP_CLK_CTRL0 REG_MDP(0x12AC) + +#ifdef MDP_CLK_CTRL1 +#undef MDP_CLK_CTRL1 +#endif +#define MDP_CLK_CTRL1 REG_MDP(0x12B4) + +#ifdef MDP_CLK_CTRL2 +#undef MDP_CLK_CTRL2 +#endif +#define MDP_CLK_CTRL2 REG_MDP(0x12BC) + +#ifdef MDP_CLK_CTRL3 +#undef MDP_CLK_CTRL3 +#endif +#define MDP_CLK_CTRL3 REG_MDP(0x13A8) + +#ifdef MDP_CLK_CTRL4 +#undef MDP_CLK_CTRL4 +#endif +#define MDP_CLK_CTRL4 REG_MDP(0x13B0) + +#ifdef MDP_CLK_CTRL5 +#undef MDP_CLK_CTRL5 +#endif +#define MDP_CLK_CTRL5 REG_MDP(0x13B8) + +#ifdef MDP_CLK_CTRL6 +#undef MDP_CLK_CTRL6 +#endif +#define MDP_CLK_CTRL6 REG_MDP(0x12C4) + +#ifdef MDP_CLK_CTRL7 +#undef MDP_CLK_CTRL7 +#endif +#define MDP_CLK_CTRL7 REG_MDP(0x13D0) + +#ifdef VBIF_VBIF_DDR_FORCE_CLK_ON +#undef VBIF_VBIF_DDR_FORCE_CLK_ON +#endif +#define VBIF_VBIF_DDR_FORCE_CLK_ON REG_MDP(0xb0004) + +#ifdef VBIF_VBIF_DDR_OUT_MAX_BURST +#undef VBIF_VBIF_DDR_OUT_MAX_BURST +#endif +#define VBIF_VBIF_DDR_OUT_MAX_BURST REG_MDP(0xb00D8) + +#ifdef VBIF_VBIF_DDR_ARB_CTRL +#undef VBIF_VBIF_DDR_ARB_CTRL +#endif +#define VBIF_VBIF_DDR_ARB_CTRL REG_MDP(0xb00F0) + +#ifdef VBIF_VBIF_DDR_RND_RBN_QOS_ARB +#undef VBIF_VBIF_DDR_RND_RBN_QOS_ARB +#endif +#define VBIF_VBIF_DDR_RND_RBN_QOS_ARB REG_MDP(0xb0124) + +#ifdef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0 +#undef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0 +#endif +#define VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0 REG_MDP(0xb0160) + +#ifdef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1 +#undef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1 +#endif +#define VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1 REG_MDP(0xb0164) + +#ifdef VBIF_VBIF_DDR_OUT_AOOO_AXI_EN +#undef VBIF_VBIF_DDR_OUT_AOOO_AXI_EN +#endif +#define VBIF_VBIF_DDR_OUT_AOOO_AXI_EN REG_MDP(0xb0178) + +#ifdef VBIF_VBIF_DDR_OUT_AX_AOOO +#undef VBIF_VBIF_DDR_OUT_AX_AOOO +#endif +#define VBIF_VBIF_DDR_OUT_AX_AOOO REG_MDP(0xb017C) + +#ifdef VBIF_VBIF_IN_RD_LIM_CONF0 +#undef VBIF_VBIF_IN_RD_LIM_CONF0 +#endif +#define VBIF_VBIF_IN_RD_LIM_CONF0 REG_MDP(0xb00B0) + +#ifdef VBIF_VBIF_IN_RD_LIM_CONF1 +#undef VBIF_VBIF_IN_RD_LIM_CONF1 +#endif +#define VBIF_VBIF_IN_RD_LIM_CONF1 REG_MDP(0xb00B4) + +#ifdef VBIF_VBIF_IN_RD_LIM_CONF2 +#undef VBIF_VBIF_IN_RD_LIM_CONF2 +#endif +#define VBIF_VBIF_IN_RD_LIM_CONF2 REG_MDP(0xb00B8) + +#ifdef VBIF_VBIF_IN_RD_LIM_CONF3 +#undef VBIF_VBIF_IN_RD_LIM_CONF3 +#endif +#define VBIF_VBIF_IN_RD_LIM_CONF3 REG_MDP(0xb00BC) + +#ifdef VBIF_VBIF_IN_WR_LIM_CONF0 +#undef VBIF_VBIF_IN_WR_LIM_CONF0 +#endif +#define VBIF_VBIF_IN_WR_LIM_CONF0 REG_MDP(0xb00C0) + +#ifdef VBIF_VBIF_IN_WR_LIM_CONF1 +#undef VBIF_VBIF_IN_WR_LIM_CONF1 +#endif +#define VBIF_VBIF_IN_WR_LIM_CONF1 REG_MDP(0xb00C4) + +#ifdef VBIF_VBIF_IN_WR_LIM_CONF2 +#undef VBIF_VBIF_IN_WR_LIM_CONF2 +#endif +#define VBIF_VBIF_IN_WR_LIM_CONF2 REG_MDP(0xb00C8) + +#ifdef VBIF_VBIF_IN_WR_LIM_CONF3 +#undef VBIF_VBIF_IN_WR_LIM_CONF3 +#endif +#define VBIF_VBIF_IN_WR_LIM_CONF3 REG_MDP(0xb00CC) + +#ifdef VBIF_VBIF_ABIT_SHORT +#undef VBIF_VBIF_ABIT_SHORT +#endif +#define VBIF_VBIF_ABIT_SHORT REG_MDP(0xb0070) + +#ifdef VBIF_VBIF_ABIT_SHORT_CONF +#undef VBIF_VBIF_ABIT_SHORT_CONF +#endif +#define VBIF_VBIF_ABIT_SHORT_CONF REG_MDP(0xb0074) + +#ifdef VBIF_VBIF_GATE_OFF_WRREQ_EN +#undef VBIF_VBIF_GATE_OFF_WRREQ_EN +#endif +#define VBIF_VBIF_GATE_OFF_WRREQ_EN REG_MDP(0xb00A8) + +#define MDP_VP_0_VIG_0_BASE REG_MDP(0x5000) +#define MDP_VP_0_VIG_1_BASE REG_MDP(0x7000) +#define MDP_VP_0_VIG_2_BASE REG_MDP(0x9000) +#define MDP_VP_0_VIG_3_BASE REG_MDP(0xB000) +#define MDP_VP_0_DMA_0_BASE REG_MDP(0x25000) +#define MDP_VP_0_DMA_1_BASE REG_MDP(0x27000) +#define MDP_VP_0_DMA_2_BASE REG_MDP(0x29000) +#define MDP_VP_0_DMA_3_BASE REG_MDP(0x2B000) +#define MDP_VP_0_MIXER_0_BASE REG_MDP(0x45000) +#define MDP_VP_0_MIXER_1_BASE REG_MDP(0x46000) +#define MDP_VP_0_MIXER_2_BASE REG_MDP(0x47000) +#define MDP_VP_0_MIXER_5_BASE REG_MDP(0x4A000) + +#define DMA_CMD_OFFSET 0x048 +#define DMA_CMD_LENGTH 0x04C + +#define INT_CTRL 0x110 +#define CMD_MODE_DMA_SW_TRIGGER 0x090 + +#define EOT_PACKET_CTRL 0x0CC +#define MISR_CMD_CTRL 0x0A0 +#define MISR_VIDEO_CTRL 0x0A4 +#define VIDEO_MODE_CTRL 0x010 +#define HS_TIMER_CTRL 0x0BC + +#define SOFT_RESET 0x118 +#define TPG_DMA_FIFO_RESET 0x1EC +#define CLK_CTRL 0x11C +#define COMMAND_MODE_MDP_CTRL2 0x1B8 +#define TEST_PATTERN_GEN_CTRL 0x15C +#define TEST_PATTERN_GEN_CMD_DMA_INIT_VAL 0x17C +#define TRIG_CTRL 0x084 +#define CTRL 0x004 +#define COMMAND_MODE_DMA_CTRL 0x03C +#define COMMAND_MODE_MDP_CTRL 0x040 +#define COMMAND_MODE_MDP_DCS_CMD_CTRL 0x044 +#define COMMAND_MODE_MDP_STREAM0_CTRL 0x058 +#define COMMAND_MODE_MDP_STREAM0_TOTAL 0x05C +#define COMMAND_MODE_MDP_STREAM1_CTRL 0x060 +#define COMMAND_MODE_MDP_STREAM1_TOTAL 0x064 +#define ERR_INT_MASK0 0x10C + +#define LANE_CTL 0x0AC +#define TIMING_CTL 0x0C4 + +#define VIDEO_MODE_ACTIVE_H 0x024 +#define VIDEO_MODE_ACTIVE_V 0x028 +#define VIDEO_MODE_TOTAL 0x02C +#define VIDEO_MODE_HSYNC 0x030 +#define VIDEO_MODE_VSYNC 0x034 +#define VIDEO_MODE_VSYNC_VPOS 0x038 + +#define VIDEO_COMPRESSION_MODE_CTRL 0x2A0 +#define VIDEO_COMPRESSION_MODE_CTRL_2 0x2A4 +#define CMD_COMPRESSION_MODE_CTRL 0x2A8 +#define CMD_COMPRESSION_MODE_CTRL_2 0x2Ac +#define CMD_COMPRESSION_MODE_CTRL_3 0x2B0 + +#define PIPE_SSPP_SRC0_ADDR 0x14 +#define PIPE_SSPP_SRC_YSTRIDE 0x24 +#define PIPE_SSPP_SRC_SIZE 0x00 +#define PIPE_SSPP_SRC_OUT_SIZE 0x0C +#define PIPE_SSPP_SRC_XY 0x08 +#define PIPE_SSPP_OUT_XY 0x10 +#define PIPE_SSPP_SRC_FORMAT 0x30 +#define PIPE_SSPP_SRC_UNPACK_PATTERN 0x34 +#define PIPE_SSPP_SRC_OP_MODE 0x38 +#define PIPE_SW_PIXEL_EXT_C0_REQ 0x108 +#define PIPE_SW_PIXEL_EXT_C1C2_REQ 0x118 +#define PIPE_SW_PIXEL_EXT_C3_REQ 0x128 + +#define LAYER_0_OUT_SIZE 0x04 +#define LAYER_0_OP_MODE 0x00 +#define LAYER_0_BORDER_COLOR_0 0x08 +#define LAYER_0_BLEND_OP(n) (0x20 + n*0x18) +#define LAYER_0_BLEND0_CONST_ALPHA(n) (0x24 + n*0x18) + +/* HW Revisions for different MDSS targets */ +#define MDSS_GET_MAJOR(rev) ((rev) >> 28) +#define MDSS_GET_MINOR(rev) (((rev) >> 16) & 0xFFF) +#define MDSS_GET_STEP(rev) ((rev) & 0xFFFF) +#define MDSS_GET_MAJOR_MINOR(rev) ((rev) >> 16) + +#define MDSS_IS_MAJOR_MINOR_MATCHING(a, b) \ + (MDSS_GET_MAJOR_MINOR((a)) == MDSS_GET_MAJOR_MINOR((b))) + +#define MDSS_MDP_REV(major, minor, step) \ + ((((major) & 0x000F) << 28) | \ + (((minor) & 0x0FFF) << 16) | \ + ((step) & 0xFFFF)) + +#define MDSS_MDP_HW_REV_620 MDSS_MDP_REV(6, 2, 0) /* Rennell v1.0 */ + +#define MDSS_MAX_LINE_BUF_WIDTH 2048 + +#define CTL_LAYER_0 0x00 +#define CTL_LAYER_1 0x04 +#define CTL_TOP 0x14 +#define CTL_FLUSH 0x18 +#define CTL_START 0x1C +#define CTL_INTF_ACTIVE 0xF4 +#define CTL_INTF_FLUSH 0x110 + +#define MDP_INTF_CONFIG 0x04 +#define MDP_HSYNC_CTL 0x08 +#define MDP_VSYNC_PERIOD_F0 0x0C +#define MDP_VSYNC_PULSE_WIDTH_F0 0x14 +#define MDP_DISPLAY_HCTL 0x3C +#define MDP_DISPLAY_V_START_F0 0x1C +#define MDP_DISPLAY_V_END_F0 0x24 +#define MDP_ACTIVE_HCTL 0x40 +#define MDP_ACTIVE_V_START_F0 0x2C +#define MDP_ACTIVE_V_END_F0 0x34 +#define MDP_UNDERFFLOW_COLOR 0x48 +#define MDP_PANEL_FORMAT 0x90 +#define MDP_PROG_FETCH_START 0x170 +#define INTF_MUX 0x25C + +/* source pipe opmode bits for flip */ +#define MDSS_MDP_OP_MODE_FLIP_UD BIT(14) +#define MDSS_MDP_OP_MODE_FLIP_LR BIT(13) + +#define MDSS_MDP_REG_DCE_SEL REG_MDP(0x1450) + +#define MDSS_MDP_PP_DSC_MODE 0x0A0 +#define MDSS_MDP_PP_DCE_DATA_OUT_SWAP 0x0C8 + +#define MDSS_MDP_DSC_COMMON_MODE 0x00 +#define MDSS_MDP_DSC_ENC 0x04 +#define MDSS_MDP_DSC_PICTURE 0x08 +#define MDSS_MDP_DSC_SLICE 0x0c +#define MDSS_MDP_DSC_CHUNK_SIZE 0x10 +#define MDSS_MDP_DSC_DELAY 0x14 +#define MDSS_MDP_DSC_SCALE_INITIAL 0x18 +#define MDSS_MDP_DSC_SCALE_DEC_INTERVAL 0x1c +#define MDSS_MDP_DSC_SCALE_INC_INTERVAL 0x20 +#define MDSS_MDP_DSC_FIRST_LINE_BPG_OFFSET 0x24 +#define MDSS_MDP_DSC_BPG_OFFSET 0x28 +#define MDSS_MDP_DSC_DSC_OFFSET 0x2c +#define MDSS_MDP_DSC_FLATNESS 0x30 +#define MDSS_MDP_DSC_RC_MODEL_SIZE 0x34 +#define MDSS_MDP_DSC_RC 0x38 +#define MDSS_MDP_DSC_RC_BUF_THRESH 0x3c /* 14 bytes */ +#define MDSS_MDP_DSC_RANGE_MIN_QP 0x74 /* 15 bytes */ +#define MDSS_MDP_DSC_RANGE_MAX_QP 0xB0 /* 15 bytes */ +#define MDSS_MDP_DSC_RANGE_BPG_OFFSET 0xEc /* 15 bytes */ + +/* Autorefresh related registers */ +#define MDP_REG_PP_0_SYNC_CONFIG_VSYNC REG_MDP(0x71004) +#define MDP_REG_PP_1_SYNC_CONFIG_VSYNC REG_MDP(0x71804) +#define MDP_REG_PP_SLAVE_SYNC_CONFIG_VSYNC REG_MDP(0x73004) +#define MDP_REG_PP_0_AUTOREFRESH_CONFIG REG_MDP(0x71030) +#define MDP_REG_PP_1_AUTOREFRESH_CONFIG REG_MDP(0x71830) +#define MDP_REG_PP_SLAVE_AUTOREFRESH_CONFIG REG_MDP(0x73030) + +/* Registers for programming the CDM hardware in bypass mode. */ +#define CDM_HDMI_PACK_OP_MODE REG_MDP (0x7A400) +#define MDP_OUT_CTL_0 REG_MDP (0x01410) +#define MDP_INTF_3_INTF_CONFIG REG_MDP (0x6C804) +#define CDM_CDWN2_OUT_SIZE REG_MDP (0x7A330) +#define CDM_CDWN2_OP_MODE REG_MDP (0x7A300) +#define CDM_CDWN2_CLAMP_OUT REG_MDP (0x7A304) +#define CDM_CSC_10_OP_MODE REG_MDP (0x7A200) + +#define HWIO_INT_CTRL_DSI_DESKEW_DONE_MASK_BMSK 0x80000000 +#define HWIO_INT_CTRL_DSI_DESKEW_DONE_MASK_SHFT 0x1f +#define HWIO_INT_CTRL_DSI_DESKEW_DONE_AK_BMSK 0x40000000 +#define HWIO_INT_CTRL_DSI_DESKEW_DONE_AK_SHFT 0x1e +#define HWIO_INT_CTRL_DSI_DESKEW_DONE_STAT_BMSK 0x40000000 +#define HWIO_INT_CTRL_DSI_DESKEW_DONE_STAT_SHFT 0x1e +#define HWIO_INT_CTRL_DSI_DYNAMIC_REFRESH_DONE_MASK_BMSK 0x20000000 +#define HWIO_INT_CTRL_DSI_DYNAMIC_REFRESH_DONE_MASK_SHFT 0x1d +#define HWIO_INT_CTRL_DSI_DYNAMIC_REFRESH_DONE_AK_BMSK 0x10000000 +#define HWIO_INT_CTRL_DSI_DYNAMIC_REFRESH_DONE_AK_SHFT 0x1c +#define HWIO_INT_CTRL_DSI_DYNAMIC_REFRESH_DONE_STAT_BMSK 0x10000000 +#define HWIO_INT_CTRL_DSI_DYNAMIC_REFRESH_DONE_STAT_SHFT 0x1c +#define HWIO_INT_CTRL_DSI_DYNAMIC_BLANKING_DMA_DONE_MASK_BMSK 0x8000000 +#define HWIO_INT_CTRL_DSI_DYNAMIC_BLANKING_DMA_DONE_MASK_SHFT 0x1b +#define HWIO_INT_CTRL_DSI_DYNAMIC_BLANKING_DMA_DONE_AK_BMSK 0x4000000 +#define HWIO_INT_CTRL_DSI_DYNAMIC_BLANKING_DMA_DONE_AK_SHFT 0x1a +#define HWIO_INT_CTRL_DSI_DYNAMIC_BLANKING_DMA_DONE_STAT_BMSK 0x4000000 +#define HWIO_INT_CTRL_DSI_DYNAMIC_BLANKING_DMA_DONE_STAT_SHFT 0x1a +#define HWIO_INT_CTRL_DSI_ERROR_MASK_BMSK 0x2000000 +#define HWIO_INT_CTRL_DSI_ERROR_MASK_SHFT 0x19 +#define HWIO_INT_CTRL_DSI_ERROR_AK_BMSK 0x1000000 +#define HWIO_INT_CTRL_DSI_ERROR_AK_SHFT 0x18 +#define HWIO_INT_CTRL_DSI_ERROR_STAT_BMSK 0x1000000 +#define HWIO_INT_CTRL_DSI_ERROR_STAT_SHFT 0x18 +#define HWIO_INT_CTRL_DSI_BTA_DONE_MASK_BMSK 0x200000 +#define HWIO_INT_CTRL_DSI_BTA_DONE_MASK_SHFT 0x15 +#define HWIO_INT_CTRL_DSI_BTA_DONE_AK_BMSK 0x100000 +#define HWIO_INT_CTRL_DSI_BTA_DONE_AK_SHFT 0x14 +#define HWIO_INT_CTRL_DSI_BTA_DONE_STAT_BMSK 0x100000 +#define HWIO_INT_CTRL_DSI_BTA_DONE_STAT_SHFT 0x14 +#define HWIO_INT_CTRL_DSI_VIDEO_MODE_DONE_MASK_BMSK 0x20000 +#define HWIO_INT_CTRL_DSI_VIDEO_MODE_DONE_MASK_SHFT 0x11 +#define HWIO_INT_CTRL_DSI_VIDEO_MODE_DONE_AK_BMSK 0x10000 +#define HWIO_INT_CTRL_DSI_VIDEO_MODE_DONE_AK_SHFT 0x10 +#define HWIO_INT_CTRL_DSI_VIDEO_MODE_DONE_STAT_BMSK 0x10000 +#define HWIO_INT_CTRL_DSI_VIDEO_MODE_DONE_STAT_SHFT 0x10 +#define HWIO_INT_CTRL_DSI_CMD_MDP_STREAM0_DONE_MASK_BMSK 0x800 +#define HWIO_INT_CTRL_DSI_CMD_MDP_STREAM0_DONE_MASK_SHFT 0xb +#define HWIO_INT_CTRL_DSI_CMD_MDP_STREAM0_DONE_AK_BMSK 0x400 +#define HWIO_INT_CTRL_DSI_CMD_MDP_STREAM0_DONE_AK_SHFT 0xa +#define HWIO_INT_CTRL_DSI_CMD_MDP_STREAM0_DONE_STAT_BMSK 0x400 +#define HWIO_INT_CTRL_DSI_CMD_MDP_STREAM0_DONE_STAT_SHFT 0xa +#define HWIO_INT_CTRL_DSI_CMD_MODE_MDP_DONE_MASK_BMSK 0x200 +#define HWIO_INT_CTRL_DSI_CMD_MODE_MDP_DONE_MASK_SHFT 0x9 +#define HWIO_INT_CTRL_DSI_CMD_MODE_MDP_DONE_AK_BMSK 0x100 +#define HWIO_INT_CTRL_DSI_CMD_MODE_MDP_DONE_AK_SHFT 0x8 +#define HWIO_INT_CTRL_DSI_CMD_MODE_MDP_DONE_STAT_BMSK 0x100 +#define HWIO_INT_CTRL_DSI_CMD_MODE_MDP_DONE_STAT_SHFT 0x8 +#define HWIO_INT_CTRL_DSI_CMD_MODE_DMA_DONE_MASK_BMSK 0x2 +#define HWIO_INT_CTRL_DSI_CMD_MODE_DMA_DONE_MASK_SHFT 0x1 +#define HWIO_INT_CTRL_DSI_CMD_MODE_DMA_DONE_AK_BMSK 0x1 +#define HWIO_INT_CTRL_DSI_CMD_MODE_DMA_DONE_AK_SHFT 0x0 +#define HWIO_INT_CTRL_DSI_CMD_MODE_DMA_DONE_STAT_BMSK 0x1 +#define HWIO_INT_CTRL_DSI_CMD_MODE_DMA_DONE_STAT_SHFT 0x0 +#define HWIO_CLK_STATUS_DSI_DYN_BYTE_INTF_CLK_ACTIVE_BMSK 0x800000 +#define HWIO_CLK_STATUS_DSI_DYN_BYTE_INTF_CLK_ACTIVE_SHFT 0x17 +#define HWIO_CLK_STATUS_DSI_HW_EVENT_CLK_ACTIVE_BMSK 0x400000 +#define HWIO_CLK_STATUS_DSI_HW_EVENT_CLK_ACTIVE_SHFT 0x16 +#define HWIO_CLK_STATUS_DSI_QDSS_CLK_ACTIVE_BMSK 0x200000 +#define HWIO_CLK_STATUS_DSI_QDSS_CLK_ACTIVE_SHFT 0x15 +#define HWIO_CLK_STATUS_DSI_LANE_LAYER_TG_BYTECLK_ACTIVE_BMSK 0x100000 +#define HWIO_CLK_STATUS_DSI_LANE_LAYER_TG_BYTECLK_ACTIVE_SHFT 0x14 +#define HWIO_CLK_STATUS_DSIPLL_UNLOCKED_CLR_BMSK 0x10000 +#define HWIO_CLK_STATUS_DSIPLL_UNLOCKED_CLR_SHFT 0x10 +#define HWIO_CLK_STATUS_DSIPLL_UNLOCKED_BMSK 0x10000 +#define HWIO_CLK_STATUS_DSIPLL_UNLOCKED_SHFT 0x10 +#define HWIO_CLK_STATUS_DSI_CAM_BIST_PCLK_ACTIVE_BMSK 0x8000 +#define HWIO_CLK_STATUS_DSI_CAM_BIST_PCLK_ACTIVE_SHFT 0xf +#define HWIO_CLK_STATUS_DSI_VID_PCLK_ACTIVE_BMSK 0x4000 +#define HWIO_CLK_STATUS_DSI_VID_PCLK_ACTIVE_SHFT 0xe +#define HWIO_CLK_STATUS_DSI_CMD_PCLK_ACTIVE_BMSK 0x2000 +#define HWIO_CLK_STATUS_DSI_CMD_PCLK_ACTIVE_SHFT 0xd +#define HWIO_CLK_STATUS_DSI_DYN_CMD_PCLK_ACTIVE_BMSK 0x1000 +#define HWIO_CLK_STATUS_DSI_DYN_CMD_PCLK_ACTIVE_SHFT 0xc +#define HWIO_CLK_STATUS_DSI_DYN_PCLK_ACTIVE_BMSK 0x400 +#define HWIO_CLK_STATUS_DSI_DYN_PCLK_ACTIVE_SHFT 0xa +#define HWIO_CLK_STATUS_DSI_AON_PCLK_ACTIVE_BMSK 0x200 +#define HWIO_CLK_STATUS_DSI_AON_PCLK_ACTIVE_SHFT 0x9 +#define HWIO_CLK_STATUS_DSI_AON_ESCCLK_ACTIVE_BMSK 0x100 +#define HWIO_CLK_STATUS_DSI_AON_ESCCLK_ACTIVE_SHFT 0x8 +#define HWIO_CLK_STATUS_DSI_DYN_BYTECLK_ACTIVE_BMSK 0x80 +#define HWIO_CLK_STATUS_DSI_DYN_BYTECLK_ACTIVE_SHFT 0x7 +#define HWIO_CLK_STATUS_DSI_AON_BYTECLK_ACTIVE_BMSK 0x40 +#define HWIO_CLK_STATUS_DSI_AON_BYTECLK_ACTIVE_SHFT 0x6 +#define HWIO_CLK_STATUS_DSI_DYN_DSICLK_ACTIVE_BMSK 0x20 +#define HWIO_CLK_STATUS_DSI_DYN_DSICLK_ACTIVE_SHFT 0x5 +#define HWIO_CLK_STATUS_DSI_AON_DSICLK_ACTIVE_BMSK 0x10 +#define HWIO_CLK_STATUS_DSI_AON_DSICLK_ACTIVE_SHFT 0x4 +#define HWIO_CLK_STATUS_DSI_DYN_AHBS_HCLK_ACTIVE_BMSK 0x8 +#define HWIO_CLK_STATUS_DSI_DYN_AHBS_HCLK_ACTIVE_SHFT 0x3 +#define HWIO_CLK_STATUS_DSI_AON_AHBS_HCLK_ACTIVE_BMSK 0x4 +#define HWIO_CLK_STATUS_DSI_AON_AHBS_HCLK_ACTIVE_SHFT 0x2 +#define HWIO_CLK_STATUS_DSI_DYN_AHBM_HCLK_ACTIVE_BMSK 0x2 +#define HWIO_CLK_STATUS_DSI_DYN_AHBM_HCLK_ACTIVE_SHFT 0x1 +#define HWIO_CLK_STATUS_DSI_AON_AHBM_HCLK_ACTIVE_BMSK 0x1 +#define HWIO_CLK_STATUS_DSI_AON_AHBM_HCLK_ACTIVE_SHFT 0x0 +#define HWIO_COMMAND_MODE_MDP_DCS_CMD_CTRL_INSERT_DCS_COMMAND_BMSK 0x10000 +#define HWIO_COMMAND_MODE_MDP_DCS_CMD_CTRL_INSERT_DCS_COMMAND_SHFT 0x10 +#define HWIO_COMMAND_MODE_DMA_CTRL_EMBEDDED_MODE_BMSK 0x10000000 +#define HWIO_COMMAND_MODE_DMA_CTRL_EMBEDDED_MODE_SHFT 0x1c +#define HWIO_COMMAND_MODE_DMA_CTRL_POWER_MODE_BMSK 0x4000000 +#define HWIO_COMMAND_MODE_DMA_CTRL_POWER_MODE_SHFT 0x1a +#define HWIO_CLK_CTRL_DSI_DMA_CLK_STOP_BMSK 0x400000 +#define HWIO_CLK_CTRL_DSI_DMA_CLK_STOP_SHFT 0x16 +#define HWIO_CLK_CTRL_DSI_FORCE_ON_LANE_LAYER_TG_BYTECLK_BMSK 0x200000 +#define HWIO_CLK_CTRL_DSI_FORCE_ON_LANE_LAYER_TG_BYTECLK_SHFT 0x15 +#define HWIO_CLK_CTRL_DSI_FORCE_ON_DYN_PCLK_BMSK 0x100000 +#define HWIO_CLK_CTRL_DSI_FORCE_ON_DYN_PCLK_SHFT 0x14 +#define HWIO_CLK_CTRL_DSI_DSICLK_HYSTERISIS1_CTRL_BMSK 0x30000 +#define HWIO_CLK_CTRL_DSI_DSICLK_HYSTERISIS1_CTRL_SHFT 0x10 +#define HWIO_CLK_CTRL_DSI_AHBM_HCLK_HYSTERISIS1_CTRL_BMSK 0xc000 +#define HWIO_CLK_CTRL_DSI_AHBM_HCLK_HYSTERISIS1_CTRL_SHFT 0xe +#define HWIO_CLK_CTRL_DSI_AHBS_HCLK_HYSTERISIS1_CTRL_BMSK 0x3000 +#define HWIO_CLK_CTRL_DSI_AHBS_HCLK_HYSTERISIS1_CTRL_SHFT 0xc +#define HWIO_CLK_CTRL_DSI_FORCE_ON_DYN_BYTECLK_BMSK 0x800 +#define HWIO_CLK_CTRL_DSI_FORCE_ON_DYN_BYTECLK_SHFT 0xb +#define HWIO_CLK_CTRL_DSI_FORCE_ON_DYN_DSICLK_BMSK 0x400 +#define HWIO_CLK_CTRL_DSI_FORCE_ON_DYN_DSICLK_SHFT 0xa +#define HWIO_CLK_CTRL_DSI_FORCE_ON_DYN_AHBM_HCLK_BMSK 0x200 +#define HWIO_CLK_CTRL_DSI_FORCE_ON_DYN_AHBM_HCLK_SHFT 0x9 +#define HWIO_CLK_CTRL_DSI_FORCE_ON_DYN_AHBS_HCLK_BMSK 0x100 +#define HWIO_CLK_CTRL_DSI_FORCE_ON_DYN_AHBS_HCLK_SHFT 0x8 +#define HWIO_CLK_CTRL_DSI_ESCCLK_ON_BMSK 0x20 +#define HWIO_CLK_CTRL_DSI_ESCCLK_ON_SHFT 0x5 +#define HWIO_CLK_CTRL_DSI_BYTECLK_ON_BMSK 0x10 +#define HWIO_CLK_CTRL_DSI_BYTECLK_ON_SHFT 0x4 +#define HWIO_CLK_CTRL_DSI_DSICLK_ON_BMSK 0x8 +#define HWIO_CLK_CTRL_DSI_DSICLK_ON_SHFT 0x3 +#define HWIO_CLK_CTRL_DSI_PCLK_ON_BMSK 0x4 +#define HWIO_CLK_CTRL_DSI_PCLK_ON_SHFT 0x2 +#define HWIO_CLK_CTRL_DSI_AHBM_SCLK_ON_BMSK 0x2 +#define HWIO_CLK_CTRL_DSI_AHBM_SCLK_ON_SHFT 0x1 +#define HWIO_CLK_CTRL_DSI_AHBS_HCLK_ON_BMSK 0x1 +#define HWIO_CLK_CTRL_DSI_AHBS_HCLK_ON_SHFT 0x0 + + +/* DSI Phy Related Registers */ +#define HWIO_DSI_0_CLKOUT_TIMING_CTRL_ADDR (MIPI_DSI0_BASE + 0x000000c4) +#define DSI_PHY_DSIPHY_CMN_CTRL_1_OFFSET (0x28) +#define DSI_0_PHY_CMN_REG_BASE DSI0_PHY_BASE + +#define DSI_0_PHY_CMN_REVISION_ID0_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x00000000) +#define DSI_0_PHY_CMN_DSI_LANE_CTRL0_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x00000098) +#define DSI_0_PHY_CMN_CTRL_0_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x00000024) +#define DSI_0_PHY_CMN_PLL_CNTRL_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x00000038) +#define DSI_0_PHY_CMN_RBUF_CTRL_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x0000001c) + +#define DSI_0_PHY_DLN0_DATALN_REG_BASE (MDSSHW_BASE + 0x00094600) +#define DSI_0_PHY_DLN0_CFG0_ADDR (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x00000000) + +#define DSI_0_PHY_DLN1_DATALN_REG_BASE (MDSSHW_BASE + 0x00094680) +#define DSI_0_PHY_DLN1_CFG0_ADDR (DSI_0_PHY_DLN1_DATALN_REG_BASE + 0x00000000) + +#define DSI_0_PHY_DLN2_DATALN_REG_BASE (MDSSHW_BASE + 0x00094700) +#define DSI_0_PHY_DLN2_CFG0_ADDR (DSI_0_PHY_DLN2_DATALN_REG_BASE + 0x00000000) + +#define DSI_0_PHY_DLN3_DATALN_REG_BASE (MDSSHW_BASE + 0x00094780) +#define DSI_0_PHY_DLN3_CFG0_ADDR (DSI_0_PHY_DLN3_DATALN_REG_BASE + 0x00000000) + +#define DSI_0_PHY_CKLN_DATALN_REG_BASE (MDSSHW_BASE + 0x00094800) +#define DSI_0_PHY_CKLN_CFG0_ADDR (DSI_0_PHY_CKLN_DATALN_REG_BASE + 0x00000000) + +#define DSI_0_PHY_DLN0_LPTX_STR_CTRL_ADDR \ + (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x00000024) +#define DSI_0_PHY_DLN0_LPRX_CTRL_ADDR \ + (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x00000028) +#define DSI_0_PHY_DLN0_PIN_SWAP_ADDR \ + (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x00000014) +#define DSI_0_PHY_DLN0_HSTX_STR_CTRL_ADDR \ + (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x00000018) +#define DSI_0_PHY_DLN0_CFG0_ADDR (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x00000000) +#define DSI_0_PHY_DLN0_CFG1_ADDR (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x00000004) +#define DSI_0_PHY_DLN0_CFG2_ADDR (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x00000008) +#define DSI_0_PHY_DLN0_CFG3_ADDR (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x0000000c) + +#define DSI_0_PHY_DLN0_OFFSET_TOP_CTRL_ADDR \ + (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x0000001c) +#define DSI_0_PHY_DLN0_OFFSET_BOT_CTRL_ADDR \ + (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x00000020) +#define DSI_0_PHY_DLN0_TX_DCTRL_ADDR \ + (DSI_0_PHY_DLN0_DATALN_REG_BASE + 0x0000002c) + +#define DSI_0_PHY_CMN_VREG_CTRL_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x00000020) +#define DSI_0_PHY_CMN_GLBL_CTRL_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x00000018) +#define DSI_0_PHY_CMN_TIMING_CTRL_0_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000ac) +#define DSI_0_PHY_CMN_TIMING_CTRL_1_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000b0) +#define DSI_0_PHY_CMN_TIMING_CTRL_2_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000b4) +#define DSI_0_PHY_CMN_TIMING_CTRL_3_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000b8) +#define DSI_0_PHY_CMN_TIMING_CTRL_4_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000bc) +#define DSI_0_PHY_CMN_TIMING_CTRL_5_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000c0) +#define DSI_0_PHY_CMN_TIMING_CTRL_6_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000c4) +#define DSI_0_PHY_CMN_TIMING_CTRL_7_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000c8) +#define DSI_0_PHY_CMN_TIMING_CTRL_8_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000cc) +#define DSI_0_PHY_CMN_TIMING_CTRL_9_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000d0) +#define DSI_0_PHY_CMN_TIMING_CTRL_10_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000d4) +#define DSI_0_PHY_CMN_TIMING_CTRL_11_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000d8) +#define DSI_0_PHY_CMN_CLK_CFG1_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x00000014) + +#define DSI_0_PHY_CMN_CTRL_2_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x0000002c) +#define DSI_0_PHY_CMN_CLK_CFG0_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x00000010) +#define DSI_0_PHY_CMN_PHY_STATUS_ADDR (DSI_0_PHY_CMN_REG_BASE + 0x000000ec) + +#define DSI_0_PHY_PLL_QLINK_COM_REG_BASE (MDSSHW_BASE + 0x00094a00) +#define DSI_1_PHY_PLL_QLINK_COM_REG_BASE (MDSSHW_BASE + 0x00096a00) +#define DSI_0_PHY_PLL_CORE_INPUT_OVERRIDE_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x000000a8) +#define DSI_0_PHY_PLL_DECIMAL_DIV_START_1_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x000000cc) +#define DSI_0_PHY_PLL_FRAC_DIV_START_LOW_1_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x000000d0) +#define DSI_0_PHY_PLL_FRAC_DIV_START_MID_1_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x000000d4) +#define DSI_0_PHY_PLL_FRAC_DIV_START_HIGH_1_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x000000d8) +#define DSI_0_PHY_PLL_PROP_GAIN_RATE_1_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x0000014c) +#define DSI_0_PHY_PLL_SYSTEM_MUXES_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000024) +#define DSI_0_PHY_PLL_LOCKDET_RATE_1_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000144) +#define DSI_0_PHY_PLL_OUTDIV_RATE_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000140) +#define DSI_0_PHY_PLL_LOCK_DELAY_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000184) +#define DSI_0_PHY_PLL_CLOCK_INVERTERS_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x0000018c) +#define DSI_0_PHY_PLL_CMODE_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x0000002c) +#define DSI_0_PHY_PLL_ANALOG_CONTROLS_ONE_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000000) +#define DSI_0_PHY_PLL_ANALOG_CONTROLS_TWO_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000004) +#define DSI_0_PHY_PLL_ANALOG_CONTROLS_THREE_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000010) +#define DSI_0_PHY_PLL_DSM_DIVIDER_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x0000001c) +#define DSI_0_PHY_PLL_FEEDBACK_DIVIDER_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000020) +#define DSI_0_PHY_PLL_CALIBRATION_SETTINGS_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000030) +#define DSI_0_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000054) +#define DSI_0_PHY_PLL_FREQ_DETECT_SETTINGS_ONE_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000064) +#define DSI_0_PHY_PLL_OUTDIV_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000094) +#define DSI_0_PHY_PLL_CORE_OVERRIDE_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x000000a4) +#define DSI_1_PHY_PLL_DIGITAL_TIMERS_TWO_ADDR \ + (DSI_1_PHY_PLL_QLINK_COM_REG_BASE + 0x000000b4) +#define DSI_0_PHY_PLL_BAND_SEL_RATE_1_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000154) +#define DSI_0_PHY_PLL_INT_GAIN_IFILT_BAND_1_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x0000015c) + +#define DSI_0_PHY_PLL_FL_INT_GAIN_PFILT_BAND_1_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000164) +#define DSI_0_PHY_PLL_LOCK_OVERRIDE_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000180) +#define DSI_0_PHY_PLL_PFILT_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x0000007c) +#define DSI_0_PHY_PLL_IFILT_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x00000080) +#define DSI_0_PHY_PLL_COMMON_STATUS_ONE_ADDR \ + (DSI_0_PHY_PLL_QLINK_COM_REG_BASE + 0x000001a0) + +void mdp_set_revision(int rev); +int mdp_get_revision(void); +int mdp_dsi_video_config(struct msm_panel_info *pinfo, struct fbcon_config *fb); +int mdp_dsi_cmd_config(struct msm_panel_info *pinfo, struct fbcon_config *fb); +int mdp_dsi_video_on(struct msm_panel_info *pinfo); +int mdp_dma_on(struct msm_panel_info *pinfo); + +#endif -- To view, visit
https://review.coreboot.org/c/coreboot/+/39613
To unsubscribe, or for help writing mail filters, visit
https://review.coreboot.org/settings
Gerrit-Project: coreboot Gerrit-Branch: master Gerrit-Change-Id: I8ff400922ae594f558cf73a5aaa433a3a93347c2 Gerrit-Change-Number: 39613 Gerrit-PatchSet: 1 Gerrit-Owner: Ravi kumar <rbokka(a)codeaurora.org> Gerrit-MessageType: newchange
10
58
0
0
← Newer
1
...
220
221
222
223
224
225
226
...
263
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
Results per page:
10
25
50
100
200