From 6c1caca70063aa707ba809a6b4695d0f0c5646f1 Mon Sep 17 00:00:00 2001 From: "Jason M. Bills" Date: Thu, 27 Feb 2020 15:57:13 -0800 Subject: Update to internal 2020-02-27 Signed-off-by: Jason M. Bills --- ...m-dts-add-DTS-for-Intel-ast2500-platforms.patch | 40 +- ...m-dts-add-DTS-for-Intel-ast2600-platforms.patch | 36 +- ...port-link-statistics-for-the-NCSI-channel.patch | 54 -- ...021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch | 403 ++++++------- .../0022-Add-AST2500-eSPI-driver.patch | 94 ++- ...c-aspeed-add-buffer-mode-transfer-support.patch | 635 ++++++++++++--------- ...-i2c-aspeed-add-DMA-mode-transfer-support.patch | 457 ++++++++------- .../0063-i2c-aspeed-add-general-call-support.patch | 20 +- .../0068-i2c-aspeed-add-H-W-timeout-support.patch | 22 +- ...add-SLAVE_ADDR_RECEIVED_PENDING-interrupt.patch | 8 +- ...d-refine-HSYNC-VSYNC-polarity-setting-log.patch | 93 --- ...-Refine-initialization-flow-in-I2C-driver.patch | 18 +- ...076-media-aspeed-clear-garbage-interrupts.patch | 74 --- ...M-dts-aspeed-g6-add-USB-virtual-hub-fixup.patch | 53 -- ...dget-aspeed-add-ast2600-compatible-string.patch | 32 -- .../linux-aspeed/0090-peci-cpupower-driver-1.patch | 405 +++++++++++++ .../0092-SPI-Quad-IO-driver-support-AST2600.patch | 136 +++++ ...ev_int-add-quick-fix-for-raw-I2C-type-reg.patch | 37 ++ ...-speed-and-duplex-settings-for-the-NCSI-c.patch | 57 ++ ...x-truncated-WrEndPointConfig-MMIO-command.patch | 40 ++ .../recipes-kernel/linux/linux-aspeed/debug.cfg | 2 + .../recipes-kernel/linux/linux-aspeed/intel.cfg | 2 + .../recipes-kernel/linux/linux-aspeed_%.bbappend | 11 +- 23 files changed, 1636 insertions(+), 1093 deletions(-) delete mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0008-Report-link-statistics-for-the-NCSI-channel.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0074-media-aspeed-refine-HSYNC-VSYNC-polarity-setting-log.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0076-media-aspeed-clear-garbage-interrupts.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0082-ARM-dts-aspeed-g6-add-USB-virtual-hub-fixup.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0083-usb-gadget-aspeed-add-ast2600-compatible-string.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0090-peci-cpupower-driver-1.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0092-SPI-Quad-IO-driver-support-AST2600.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0093-ipmi-ipmb_dev_int-add-quick-fix-for-raw-I2C-type-reg.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0094-Return-link-speed-and-duplex-settings-for-the-NCSI-c.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0096-Fix-truncated-WrEndPointConfig-MMIO-command.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/debug.cfg (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux') diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2500-platforms.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2500-platforms.patch index baf9dba9a..31061624c 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2500-platforms.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2500-platforms.patch @@ -1,4 +1,4 @@ -From 89dec433cd2fcfcb8690b315bb4e787d53de2296 Mon Sep 17 00:00:00 2001 +From da2fecd5d5b3f69bcc4d07fd1265415bd350e5a6 Mon Sep 17 00:00:00 2001 From: Yuan Li Date: Tue, 19 Sep 2017 15:55:39 +0800 Subject: [PATCH] arm: dts: add DTS for Intel ast2500 platforms @@ -14,17 +14,19 @@ Signed-off-by: Zhu, Yunge Signed-off-by: Qiang XU Signed-off-by: Chen Yugang Signed-off-by: Zhikui Ren +Signed-off-by: jayaprakash Mutyala +Signed-off-by: AppaRao Puli --- - arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts | 471 +++++++++++++++++++++++++ - 1 file changed, 471 insertions(+) + arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts | 460 +++++++++++++++++++++++++ + 1 file changed, 460 insertions(+) create mode 100644 arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts diff --git a/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts b/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts new file mode 100644 -index 0000000..6ded94d +index 0000000..1fe6240 --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts -@@ -0,0 +1,470 @@ +@@ -0,0 +1,460 @@ +/dts-v1/; + +#include "aspeed-g5.dtsi" @@ -114,7 +116,7 @@ index 0000000..6ded94d + + beeper { + compatible = "pwm-beeper"; -+ pwms = <&timer 5 1000000 0>; ++ pwms = <&timer 6 1000000 0>; + }; +}; + @@ -180,8 +182,8 @@ index 0000000..6ded94d + /*D0-D7*/ "","","","","","","","", + /*E0-E7*/ "RESET_BUTTON","RESET_OUT","POWER_BUTTON","POWER_OUT","","DEBUG_EN_N","","", + /*F0-F7*/ "NMI_OUT","","","","CPU_ERR0","CPU_ERR1","PLTRST_N","PRDY_N", -+ /*G0-G7*/ "CPU_ERR2","CPU_CATERR","PCH_BMC_THERMTRIP","","","FM_BMC_BOARD_SKU_ID5_N","","", -+ /*H0-H7*/ "","","","","","","","", ++ /*G0-G7*/ "CPU_ERR2","CPU_CATERR","PCH_BMC_THERMTRIP","LCP_ENTER_BUTTON","LCP_LEFT_BUTTON","FM_BMC_BOARD_SKU_ID5_N","","", ++ /*H0-H7*/ "","","","FM_NODE_ID_1","FM_NODE_ID_2","FM_NODE_ID_3","FM_NODE_ID_4","FM_240VA_STATUS", + /*I0-I7*/ "FM_SYS_FAN0_PRSNT_D_N","FM_SYS_FAN1_PRSNT_D_N","FM_SYS_FAN2_PRSNT_D_N","FM_SYS_FAN3_PRSNT_D_N","FM_SYS_FAN4_PRSNT_D_N","FM_SYS_FAN5_PRSNT_D_N","","", + /*J0-J7*/ "","","","","","","","", + /*K0-K7*/ "","","","","","","","", @@ -191,7 +193,7 @@ index 0000000..6ded94d + /*O0-O7*/ "","","","","","","","", + /*P0-P7*/ "","","","","","","","", + /*Q0-Q7*/ "","","","","","","","PWR_DEBUG_N", -+ /*R0-R7*/ "","XDP_PRST_N","","","","","","", ++ /*R0-R7*/ "","XDP_PRST_N","","","","","","CHASSIS_INTRUSION", + /*S0-S7*/ "REMOTE_DEBUG_ENABLE","SYSPWROK","RSMRST_N","","","","","", + /*T0-T7*/ "","","","","","","","", + /*U0-U7*/ "","","","","","","","", @@ -224,8 +226,8 @@ index 0000000..6ded94d + + /* SGPIO input lines */ + /*IA0-IA7*/ "CPU1_PRESENCE","CPU1_THERMTRIP","CPU1_VRHOT","CPU1_FIVR_FAULT","CPU1_MEM_ABCD_VRHOT","CPU1_MEM_EFGH_VRHOT","","", -+ /*IB0-IB7*/ "","","CPU2_PRESENCE","CPU2_THERMTRIP","CPU2_VRHOT","CPU2_FIVR_FAULT","CPU2_MEM_ABCD_VRHOT","CPU2_MEM_EFGH_VRHOT", -+ /*IC0-IC7*/ "","","","","","","","", ++ /*IB0-IB7*/ "CPU1_MISMATCH","CPU1_MEM_THERM_EVENT","CPU2_PRESENCE","CPU2_THERMTRIP","CPU2_VRHOT","CPU2_FIVR_FAULT","CPU2_MEM_ABCD_VRHOT","CPU2_MEM_EFGH_VRHOT", ++ /*IC0-IC7*/ "","","CPU2_MISMATCH","CPU2_MEM_THERM_EVENT","","","","", + /*ID0-ID7*/ "","","","","","","","", + /*IE0-IE7*/ "","","","","","","","", + /*IF0-IF7*/ "","","","","","","","", @@ -365,11 +367,6 @@ index 0000000..6ded94d + aspeed,dma-buf-size = <4095>; + aspeed,hw-timeout-ms = <300>; + status = "okay"; -+ -+ hsbp0@10 { -+ compatible = "slave-mqueue"; -+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>; -+ }; +}; + +&i2c5 { @@ -378,11 +375,6 @@ index 0000000..6ded94d + aspeed,dma-buf-size = <4095>; + aspeed,hw-timeout-ms = <300>; + status = "okay"; -+ -+ smlink0@10 { -+ compatible = "slave-mqueue"; -+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>; -+ }; +}; + +&i2c6 { @@ -480,9 +472,9 @@ index 0000000..6ded94d + * pinctrl-0 = <&pinctrl_timer5_default &pinctrl_timer6_default + * &pinctrl_timer7_default &pinctrl_timer8_default>; + */ -+ fttmr010,pwm-outputs = <5>; ++ fttmr010,pwm-outputs = <6>; + pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_timer5_default>; ++ pinctrl-0 = <&pinctrl_timer6_default>; + #pwm-cells = <3>; + status = "okay"; +}; @@ -495,6 +487,6 @@ index 0000000..6ded94d +&vhub { + status = "okay"; +}; --- +-- 2.7.4 diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch index 34490822e..cc025e1f8 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch @@ -1,4 +1,4 @@ -From 57363b496c6eb832b0c3407ee997fdee09f4007f Mon Sep 17 00:00:00 2001 +From 733ea1e7c0fd70ce372efcc8250bb2baebd74b68 Mon Sep 17 00:00:00 2001 From: Vernon Mauery Date: Tue, 19 Sep 2017 15:55:39 +0800 Subject: [PATCH] arm: dts: add DTS for Intel ast2600 platforms @@ -8,17 +8,19 @@ Add the DTS file for Intel ast2600-based systems. Signed-off-by: Vernon Mauery Signed-off-by: Jae Hyun Yoo Signed-off-by: Chen Yugang +Signed-off-by: Kuiying Wang +Signed-off-by: arun-pm --- - arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts | 507 +++++++++++++++++++++++++ - 1 file changed, 507 insertions(+) + arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts | 497 +++++++++++++++++++++++++ + 1 file changed, 497 insertions(+) create mode 100644 arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts diff --git a/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts b/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts new file mode 100644 -index 000000000000..1ad46e8bc69b +index 000000000000..5bc76dd069af --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts -@@ -0,0 +1,507 @@ +@@ -0,0 +1,497 @@ +// SPDX-License-Identifier: GPL-2.0+ +/dts-v1/; + @@ -76,8 +78,8 @@ index 000000000000..1ad46e8bc69b + compatible = "iio-hwmon"; + io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>, + <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>, -+ <&adc1 8>, <&adc1 9>, <&adc1 10>, <&adc1 11>, -+ <&adc1 12>, <&adc1 13>, <&adc1 14>, <&adc1 15>; ++ <&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>, ++ <&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>; + }; + + leds { @@ -112,14 +114,15 @@ index 000000000000..1ad46e8bc69b + reg = <0x0>; + #address-cells = <1>; + #size-cells = <1>; -+ spi-max-frequency = <10000000>; ++ spi-max-frequency = <40000000>; ++ spi-tx-bus-width = <4>; + m25p,fast-read; +#include "openbmc-flash-layout-intel-64MB.dtsi" + }; +}; + +&espi { -+ status = "disabled"; /* FIXME: Use H/W handshaking */ ++ status = "okay"; +}; + +&peci0 { @@ -173,14 +176,14 @@ index 000000000000..1ad46e8bc69b + gpio-line-names = + /*A0-A7*/ "","","","","SMB_CPU_PIROM_SCL","SMB_CPU_PIROM_SDA","SMB_IPMB_STBY_LVC3_R_SCL","SMB_IPMB_STBY_LVC3_R_SDA", + /*B0-B7*/ "FM_1200VA_OC","NMI_OUT","IRQ_SMB3_M2_ALERT_N","","RGMII_BMC_RMM4_LVC3_R_MDC","RGMII_BMC_RMM4_LVC3_R_MDIO","FM_BMC_BMCINIT_R","FP_ID_LED_N", -+ /*C0-C7*/ "FM_FORCE_BMC_UPDATE_N","RST_RGMII_PHYRST_N","FM_TPM_EN_PULSE","FM_BMC_CRASHLOG_TRIG_N","IRQ_BMC_PCH_NMI_R","FM_CPU1_DISABLE_COD_N","","", ++ /*C0-C7*/ "FM_FORCE_BMC_UPDATE_N","RST_RGMII_PHYRST_N","FM_TPM_EN_PULSE","FM_BMC_CRASHLOG_TRIG_N","IRQ_BMC_PCH_NMI_R","FM_CPU1_DISABLE_COD_N","FM_4S_8S_N_MODE","FM_STANDALONE_MODE_N", + /*D0-D7*/ "CPU_ERR0","CPU_ERR1","CPU_ERR2","PRDY_N","FM_SPD_SWITCH_CTRL_N","","","", + /*E0-E7*/ "FM_SKT1_FAULT_LED","FM_SKT0_FAULT_LED","CLK_50M_CKMNG_BMCB","FM_BMC_BOARD_REV_ID2_N","","","","", + /*F0-F7*/ "FM_BMC_BOARD_SKU_ID0_N","FM_BMC_BOARD_SKU_ID1_N","FM_BMC_BOARD_SKU_ID2_N","FM_BMC_BOARD_SKU_ID3_N","FM_BMC_BOARD_SKU_ID4_N","FM_BMC_BOARD_SKU_ID5_N","ID_BUTTON","PS_PWROK", + /*G0-G7*/ "FM_SMB_BMC_NVME_LVC3_ALERT_N","RST_BMC_I2C_M2_R_N","FP_LED_STATUS_GREEN_N","FP_LED_STATUS_AMBER_N","FM_BMC_BOARD_REV_ID0_N","FM_BMC_BOARD_REV_ID1_N","FM_BMC_CPU_FBRK_OUT_R_N","DBP_PRESENT_IN_R2_N", + /*H0-H7*/ "SGPIO_BMC_CLK_R","SGPIO_BMC_LD_R","SGPIO_BMC_DOUT_R","SGPIO_BMC_DIN","PLTRST_N","CPU_CATERR","PCH_BMC_THERMTRIP","", + /*I0-I7*/ "JTAG_ASD_NTRST_R_N","JTAG_ASD_TDI_R","JTAG_ASD_TCK_R","JTAG_ASD_TMS_R","JTAG_ASD_TDO","FM_BMC_PWRBTN_OUT_R_N","FM_BMC_PWR_BTN_N","", -+ /*J0-J7*/ "SMB_CHASSENSOR_STBY_LVC3_SCL","SMB_CHASSENSOR_STBY_LVC3_SDA","","","","","","", ++ /*J0-J7*/ "SMB_CHASSENSOR_STBY_LVC3_SCL","SMB_CHASSENSOR_STBY_LVC3_SDA","FM_NODE_ID0","FM_NODE_ID1","","","","", + /*K0-K7*/ "SMB_HSBP_STBY_LVC3_R_SCL","SMB_HSBP_STBY_LVC3_R_SDA","SMB_SMLINK0_STBY_LVC3_R2_SCL","SMB_SMLINK0_STBY_LVC3_R2_SDA","SMB_TEMPSENSOR_STBY_LVC3_R_SCL","SMB_TEMPSENSOR_STBY_LVC3_R_SDA","SMB_PMBUS_SML1_STBY_LVC3_R_SCL","SMB_PMBUS_SML1_STBY_LVC3_R_SDA", + /*L0-L7*/ "SMB_PCIE_STBY_LVC3_R_SCL","SMB_PCIE_STBY_LVC3_R_SDA","SMB_HOST_STBY_BMC_LVC3_R_SCL","SMB_HOST_STBY_BMC_LVC3_R_SDA","PREQ_N","DEBUG_EN_N","V_BMC_GFX_HSYNC_R","V_BMC_GFX_VSYNC_R", + /*M0-M7*/ "SPA_CTS_N","SPA_DCD_N","SPA_DSR_N","PU_SPA_RI_N","SPA_DTR_N","SPA_RTS_N","SPA_SOUT","SPA_SIN", @@ -385,11 +388,6 @@ index 000000000000..1ad46e8bc69b + /* SMB_HSBP_STBY_LVC3_R */ + multi-master; + status = "okay"; -+ -+ hsbp0@10 { -+ compatible = "slave-mqueue"; -+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>; -+ }; +}; + +&i2c5 { @@ -397,11 +395,6 @@ index 000000000000..1ad46e8bc69b + bus-frequency = <1000000>; + multi-master; + status = "okay"; -+ -+ smlink0@10 { -+ compatible = "slave-mqueue"; -+ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>; -+ }; +}; + +&i2c6 { @@ -414,7 +407,6 @@ index 000000000000..1ad46e8bc69b + /* SMB_PMBUS_SML1_STBY_LVC3_R */ + multi-master; + #retries = <3>; -+ + status = "okay"; +}; + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0008-Report-link-statistics-for-the-NCSI-channel.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0008-Report-link-statistics-for-the-NCSI-channel.patch deleted file mode 100644 index 7e38110af..000000000 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0008-Report-link-statistics-for-the-NCSI-channel.patch +++ /dev/null @@ -1,54 +0,0 @@ -From b08fba62b18ecb04d3e7dafac6bd819dd9b90d35 Mon Sep 17 00:00:00 2001 -From: Johnathan Mantey -Date: Thu, 1 Aug 2019 11:29:41 -0700 -Subject: [PATCH] Report link statistics for the NCSI channel - -The ftgmac driver does not report the link statistics for the NCSI -channel used for the shared NICs attached to the BMC. Report a fixed -value for the NSCI interface. - -Change-Id: Idb65ca1ce07f06a883417ee44df30ea2c8483107 -Signed-off-by: Johnathan Mantey ---- - drivers/net/ethernet/faraday/ftgmac100.c | 22 +++++++++++++++++++++- - 1 file changed, 21 insertions(+), 1 deletion(-) - -diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c -index 2e5fba354412..b1eb3abe759b 100644 ---- a/drivers/net/ethernet/faraday/ftgmac100.c -+++ b/drivers/net/ethernet/faraday/ftgmac100.c -@@ -1218,10 +1218,30 @@ static int ftgmac100_set_pauseparam(struct net_device *netdev, - return 0; - } - -+int ftgmac100_ethtool_get_link_ksettings(struct net_device *netdev, -+ struct ethtool_link_ksettings *cmd) -+{ -+ struct phy_device *phydev = netdev->phydev; -+ struct ftgmac100 *priv = netdev_priv(netdev); -+ int retval = 0; -+ -+ if (phydev) { -+ phy_ethtool_ksettings_get(phydev, cmd); -+ } else if (priv->use_ncsi) { -+ cmd->base.speed = SPEED_100; -+ cmd->base.duplex = DUPLEX_FULL; -+ cmd->base.autoneg = 0; -+ } else { -+ retval = -ENODEV; -+ } -+ -+ return retval; -+} -+ - static const struct ethtool_ops ftgmac100_ethtool_ops = { - .get_drvinfo = ftgmac100_get_drvinfo, - .get_link = ethtool_op_get_link, -- .get_link_ksettings = phy_ethtool_get_link_ksettings, -+ .get_link_ksettings = ftgmac100_ethtool_get_link_ksettings, - .set_link_ksettings = phy_ethtool_set_link_ksettings, - .nway_reset = phy_ethtool_nway_reset, - .get_ringparam = ftgmac100_get_ringparam, --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch index d66e84beb..b4b1bcad8 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0021-Initial-Port-of-Aspeed-LPC-SIO-driver.patch @@ -1,4 +1,4 @@ -From c111aac36e2f4fa1149662c85883407315ba76a6 Mon Sep 17 00:00:00 2001 +From 39f76bd49fd481999cf51fbdfbea3e820efc7227 Mon Sep 17 00:00:00 2001 From: Yong Li Date: Mon, 13 Nov 2017 16:29:44 +0800 Subject: [PATCH] Aspeed LPC SIO driver @@ -13,9 +13,9 @@ Signed-off-by: Jae Hyun Yoo arch/arm/boot/dts/aspeed-g5.dtsi | 7 + drivers/soc/aspeed/Kconfig | 7 + drivers/soc/aspeed/Makefile | 1 + - drivers/soc/aspeed/aspeed-lpc-sio.c | 450 +++++++++++++++++++++ - include/uapi/linux/aspeed-lpc-sio.h | 44 ++ - 7 files changed, 533 insertions(+) + drivers/soc/aspeed/aspeed-lpc-sio.c | 410 +++++++++++++++++++++ + include/uapi/linux/aspeed-lpc-sio.h | 45 +++ + 7 files changed, 494 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/aspeed/aspeed-lpc-sio.txt create mode 100644 drivers/soc/aspeed/aspeed-lpc-sio.c create mode 100644 include/uapi/linux/aspeed-lpc-sio.h @@ -110,14 +110,15 @@ index f3ff29b874ed..2e547cc47e62 100644 obj-$(CONFIG_ASPEED_P2A_CTRL) += aspeed-p2a-ctrl.o diff --git a/drivers/soc/aspeed/aspeed-lpc-sio.c b/drivers/soc/aspeed/aspeed-lpc-sio.c new file mode 100644 -index 000000000000..c717a3182320 +index 000000000000..d4a4da112ff4 --- /dev/null +++ b/drivers/soc/aspeed/aspeed-lpc-sio.c -@@ -0,0 +1,450 @@ +@@ -0,0 +1,410 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2012-2017 ASPEED Technology Inc. -+// Copyright (c) 2017-2019 Intel Corporation ++// Copyright (c) 2017-2020 Intel Corporation + ++#include +#include +#include +#include @@ -128,62 +129,67 @@ index 000000000000..c717a3182320 +#include +#include + -+#include -+ -+#define SOC_NAME "aspeed" -+#define DEVICE_NAME "lpc-sio" -+ -+#define AST_LPC_SWCR0300 0x0 -+#define LPC_PWRGD_STS (1 << 30) -+#define LPC_PWRGD_RISING_EVT_STS (1 << 29) -+#define LPC_PWRGD_FALLING_EVT_STS (1 << 28) -+#define LPC_PWRBTN_STS (1 << 27) -+#define LPC_PWRBTN_RISING_EVT_STS (1 << 26) -+#define LPC_PWRBTN_FALLING_EVT_STS (1 << 25) -+#define LPC_S5N_STS (1 << 21) -+#define LPC_S5N_RISING_EVT_STS (1 << 20) -+#define LPC_S5N_FALLING_EVT_STS (1 << 19) -+#define LPC_S3N_STS (1 << 18) -+#define LPC_S3N_RISING_EVT_STS (1 << 17) -+#define LPC_S3N_FALLING_EVT_STS (1 << 16) -+#define LPC_PWBTO_RAW_STS (1 << 15) -+#define LPC_LAST_ONCTL_STS (1 << 14) -+#define LPC_WAS_PFAIL_STS (1 << 13) -+#define LPC_POWER_UP_FAIL_STS (1 << 12) /* Crowbar */ -+#define LPC_PWRBTN_OVERRIDE_STS (1 << 11) -+ -+#define AST_LPC_SWCR0704 0x4 -+ -+#define AST_LPC_SWCR0B08 0x8 -+#define LPC_PWREQ_OUTPUT_LEVEL (1 << 25) -+#define LPC_PWBTO_OUTPUT_LEVEL (1 << 24) -+#define LPC_ONCTL_STS (1 << 15) -+#define LPC_ONCTL_GPIO_LEVEL (1 << 14) -+#define LPC_ONCTL_EN_GPIO_OUTPUT (1 << 13) -+#define LPC_ONCTL_EN_GPIO_MODE (1 << 12) -+ -+#define AST_LPC_SWCR0F0C 0xC -+#define AST_LPC_SWCR1310 0x10 -+#define AST_LPC_SWCR1714 0x14 -+#define AST_LPC_SWCR1B18 0x18 -+#define AST_LPC_SWCR1F1C 0x1C -+#define AST_LPC_ACPIE3E0 0x20 -+#define AST_LPC_ACPIC1C0 0x24 -+#define AST_LPC_ACPIB3B0 0x28 -+#define AST_LPC_ACPIB7B4 0x2C ++#define SOC_NAME "aspeed" ++#define DEVICE_NAME "lpc-sio" ++ ++#define AST_LPC_SWCR0300 0x00 ++#define LPC_PWRGD_STS BIT(30) ++#define LPC_PWRGD_RISING_EVT_STS BIT(29) ++#define LPC_PWRGD_FALLING_EVT_STS BIT(28) ++#define LPC_PWRBTN_STS BIT(27) ++#define LPC_PWRBTN_RISING_EVT_STS BIT(26) ++#define LPC_PWRBTN_FALLING_EVT_STS BIT(25) ++#define LPC_S5N_STS BIT(21) ++#define LPC_S5N_RISING_EVT_STS BIT(20) ++#define LPC_S5N_FALLING_EVT_STS BIT(19) ++#define LPC_S3N_STS BIT(18) ++#define LPC_S3N_RISING_EVT_STS BIT(17) ++#define LPC_S3N_FALLING_EVT_STS BIT(16) ++#define LPC_PWBTO_RAW_STS BIT(15) ++#define LPC_LAST_ONCTL_STS BIT(14) ++#define LPC_WAS_PFAIL_STS BIT(13) ++#define LPC_POWER_UP_FAIL_STS BIT(12) /* Crowbar */ ++#define LPC_PWRBTN_OVERRIDE_STS BIT(11) ++#define LPC_BMC_TRIG_WAKEUP_EVT_STS BIT(8) ++ ++#define AST_LPC_SWCR0704 0x04 ++#define LPC_BMC_TRIG_WAKEUP_EVT_EN BIT(8) ++ ++#define AST_LPC_SWCR0B08 0x08 ++#define LPC_PWREQ_OUTPUT_LEVEL BIT(25) ++#define LPC_PWBTO_OUTPUT_LEVEL BIT(24) ++#define LPC_ONCTL_STS BIT(15) ++#define LPC_ONCTL_GPIO_LEVEL BIT(14) ++#define LPC_ONCTL_EN_GPIO_OUTPUT BIT(13) ++#define LPC_ONCTL_EN_GPIO_MODE BIT(12) ++#define LPC_BMC_TRIG_WAKEUP_EVT BIT(6) ++ ++#define AST_LPC_SWCR0F0C 0x0C ++#define AST_LPC_SWCR1310 0x10 ++#define AST_LPC_SWCR1714 0x14 ++#define AST_LPC_SWCR1B18 0x18 ++#define AST_LPC_SWCR1F1C 0x1C ++#define AST_LPC_ACPIE3E0 0x20 ++#define AST_LPC_ACPIC1C0 0x24 ++ ++#define AST_LPC_ACPIB3B0 0x28 ++#define LPC_BMC_TRIG_SCI_EVT_STS BIT(8) ++ ++#define AST_LPC_ACPIB7B4 0x2C ++#define LPC_BMC_TRIG_SCI_EVT_EN BIT(8) + +struct aspeed_lpc_sio { -+ struct miscdevice miscdev; -+ struct regmap *regmap; -+ struct clk *clk; -+ struct semaphore lock; -+ unsigned int reg_base; ++ struct miscdevice miscdev; ++ struct regmap *regmap; ++ struct clk *clk; ++ struct semaphore lock; ++ unsigned int reg_base; +}; + +static struct aspeed_lpc_sio *file_aspeed_lpc_sio(struct file *file) +{ + return container_of(file->private_data, struct aspeed_lpc_sio, -+ miscdev); ++ miscdev); +} + +static int aspeed_lpc_sio_open(struct inode *inode, struct file *filp) @@ -196,7 +202,8 @@ index 000000000000..c717a3182320 + LPC_S5N_FALLING_EVT_STS | \ + LPC_S3N_RISING_EVT_STS | \ + LPC_S3N_FALLING_EVT_STS) -+/************************************* ++ ++/* + * SLPS3n SLPS5n State + * --------------------------------- + * 1 1 S12 @@ -205,33 +212,20 @@ index 000000000000..c717a3182320 + ************************************* + */ + -+static long sio_get_acpi_state(struct aspeed_lpc_sio *lpc_sio, -+ struct sio_ioctl_data *sio_data) ++static void sio_get_acpi_state(struct aspeed_lpc_sio *lpc_sio, ++ struct sio_ioctl_data *sio_data) +{ -+ u32 reg; -+ u32 val; -+ int rc; ++ u32 reg, val; + + reg = lpc_sio->reg_base + AST_LPC_SWCR0300; -+ rc = regmap_read(lpc_sio->regmap, reg, &val); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg); -+ return rc; -+ } ++ regmap_read(lpc_sio->regmap, reg, &val); + + /* update the ACPI state event status */ + if (sio_data->param != 0) { + if (val & LPC_SLP3N5N_EVENT_STATUS) { + sio_data->param = 1; -+ rc = regmap_write(lpc_sio->regmap, reg, -+ LPC_SLP3N5N_EVENT_STATUS); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_write() failed with %d(reg:0x%x)\n", -+ rc, reg); -+ return rc; -+ } ++ regmap_write(lpc_sio->regmap, reg, ++ LPC_SLP3N5N_EVENT_STATUS); + } else { + sio_data->param = 0; + } @@ -243,85 +237,52 @@ index 000000000000..c717a3182320 + sio_data->data = ACPI_STATE_S3I; + else + sio_data->data = ACPI_STATE_S45; -+ -+ return 0; +} + +#define LPC_PWRGD_EVENT_STATUS ( \ + LPC_PWRGD_RISING_EVT_STS | \ + LPC_PWRGD_FALLING_EVT_STS) + -+static long sio_get_pwrgd_status(struct aspeed_lpc_sio *lpc_sio, -+ struct sio_ioctl_data *sio_data) ++static void sio_get_pwrgd_status(struct aspeed_lpc_sio *lpc_sio, ++ struct sio_ioctl_data *sio_data) +{ -+ u32 reg; -+ u32 val; -+ int rc; ++ u32 reg, val; + + reg = lpc_sio->reg_base + AST_LPC_SWCR0300; -+ rc = regmap_read(lpc_sio->regmap, reg, &val); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg); -+ return rc; -+ } ++ regmap_read(lpc_sio->regmap, reg, &val); + + /* update the PWRGD event status */ + if (sio_data->param != 0) { + if (val & LPC_PWRGD_EVENT_STATUS) { + sio_data->param = 1; -+ rc = regmap_write(lpc_sio->regmap, reg, -+ LPC_PWRGD_EVENT_STATUS); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_write() failed with %d(reg:0x%x)\n", -+ rc, reg); -+ return rc; -+ } ++ regmap_write(lpc_sio->regmap, reg, ++ LPC_PWRGD_EVENT_STATUS); + } else { + sio_data->param = 0; + } + } + + sio_data->data = (val & LPC_PWRGD_STS) != 0 ? 1 : 0; -+ -+ return 0; +} + -+static long sio_get_onctl_status(struct aspeed_lpc_sio *lpc_sio, -+ struct sio_ioctl_data *sio_data) ++static void sio_get_onctl_status(struct aspeed_lpc_sio *lpc_sio, ++ struct sio_ioctl_data *sio_data) +{ -+ u32 reg; -+ u32 val; -+ int rc; ++ u32 reg, val; + + reg = lpc_sio->reg_base + AST_LPC_SWCR0B08; -+ rc = regmap_read(lpc_sio->regmap, reg, &val); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg); -+ return rc; -+ } ++ regmap_read(lpc_sio->regmap, reg, &val); + + sio_data->data = (val & LPC_ONCTL_STS) != 0 ? 1 : 0; -+ -+ return 0; +} + -+static long sio_set_onctl_gpio(struct aspeed_lpc_sio *lpc_sio, -+ struct sio_ioctl_data *sio_data) ++static void sio_set_onctl_gpio(struct aspeed_lpc_sio *lpc_sio, ++ struct sio_ioctl_data *sio_data) +{ -+ u32 reg; -+ u32 val; -+ int rc; ++ u32 reg, val; + + reg = lpc_sio->reg_base + AST_LPC_SWCR0B08; -+ rc = regmap_read(lpc_sio->regmap, reg, &val); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg); -+ return rc; -+ } ++ regmap_read(lpc_sio->regmap, reg, &val); + + /* Enable ONCTL GPIO mode */ + if (sio_data->param != 0) { @@ -333,112 +294,103 @@ index 000000000000..c717a3182320 + else + val &= ~LPC_ONCTL_GPIO_LEVEL; + -+ rc = regmap_write(lpc_sio->regmap, reg, val); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_write() failed with %d(reg:0x%x)\n", rc, reg); -+ return rc; -+ } ++ regmap_write(lpc_sio->regmap, reg, val); + } else { + val &= ~LPC_ONCTL_EN_GPIO_MODE; -+ rc = regmap_write(lpc_sio->regmap, reg, val); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_write() failed with %d(reg:0x%x)\n", rc, reg); -+ return rc; -+ } ++ regmap_write(lpc_sio->regmap, reg, val); + } -+ -+ return 0; +} + -+static long sio_get_pwrbtn_override(struct aspeed_lpc_sio *lpc_sio, -+ struct sio_ioctl_data *sio_data) ++static void sio_get_pwrbtn_override(struct aspeed_lpc_sio *lpc_sio, ++ struct sio_ioctl_data *sio_data) +{ -+ u32 reg; -+ u32 val; -+ int rc; ++ u32 reg, val; + + reg = lpc_sio->reg_base + AST_LPC_SWCR0300; -+ rc = regmap_read(lpc_sio->regmap, reg, &val); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg); -+ return rc; -+ } ++ regmap_read(lpc_sio->regmap, reg, &val); + + /* clear the PWRBTN OVERRIDE status */ -+ if (sio_data->param != 0) { -+ if (val & LPC_PWRBTN_OVERRIDE_STS) { -+ rc = regmap_write(lpc_sio->regmap, reg, -+ LPC_PWRBTN_OVERRIDE_STS); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_write() failed with %d(reg:0x%x)\n", -+ rc, reg); -+ return rc; -+ } -+ } -+ } ++ if (sio_data->param != 0 && val & LPC_PWRBTN_OVERRIDE_STS) ++ regmap_write(lpc_sio->regmap, reg, LPC_PWRBTN_OVERRIDE_STS); + + sio_data->data = (val & LPC_PWRBTN_OVERRIDE_STS) != 0 ? 1 : 0; -+ -+ return 0; +} + -+static long sio_get_pfail_status(struct aspeed_lpc_sio *lpc_sio, -+ struct sio_ioctl_data *sio_data) ++static void sio_get_pfail_status(struct aspeed_lpc_sio *lpc_sio, ++ struct sio_ioctl_data *sio_data) +{ -+ u32 reg; -+ u32 val; -+ int rc; ++ u32 reg, val; + + reg = lpc_sio->reg_base + AST_LPC_SWCR0300; -+ rc = regmap_read(lpc_sio->regmap, reg, &val); -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_read() failed with %d(reg:0x%x)\n", rc, reg); -+ return rc; -+ } ++ regmap_read(lpc_sio->regmap, reg, &val); + + /* [ASPEED]: SWCR_03_00[13] (Was_pfail: default 1) is used to identify + * this current booting is from AC loss (not DC loss) if FW cleans this + * bit after booting successfully every time. + **********************************************************************/ + if (val & LPC_WAS_PFAIL_STS) { -+ rc = regmap_write(lpc_sio->regmap, reg, 0); /* W0C */ -+ if (rc) { -+ dev_err(lpc_sio->miscdev.parent, -+ "regmap_write() failed with %d(reg:0x%x)\n", rc, reg); -+ return rc; -+ } ++ regmap_write(lpc_sio->regmap, reg, 0); /* W0C */ + sio_data->data = 1; + } else { + sio_data->data = 0; + } ++} + -+ return 0; ++static void sio_set_bmc_sci_event(struct aspeed_lpc_sio *lpc_sio, ++ struct sio_ioctl_data *sio_data) ++{ ++ u32 reg; ++ ++ if (sio_data->param) { ++ reg = lpc_sio->reg_base + AST_LPC_ACPIB7B4; ++ regmap_write_bits(lpc_sio->regmap, reg, ++ LPC_BMC_TRIG_SCI_EVT_EN, ++ LPC_BMC_TRIG_SCI_EVT_EN); ++ ++ reg = lpc_sio->reg_base + AST_LPC_SWCR0704; ++ regmap_write_bits(lpc_sio->regmap, reg, ++ LPC_BMC_TRIG_WAKEUP_EVT_EN, ++ LPC_BMC_TRIG_WAKEUP_EVT_EN); ++ ++ reg = lpc_sio->reg_base + AST_LPC_SWCR0B08; ++ regmap_write_bits(lpc_sio->regmap, reg, ++ LPC_BMC_TRIG_WAKEUP_EVT, ++ LPC_BMC_TRIG_WAKEUP_EVT); ++ } else { ++ reg = lpc_sio->reg_base + AST_LPC_SWCR0300; ++ regmap_write_bits(lpc_sio->regmap, reg, ++ LPC_BMC_TRIG_WAKEUP_EVT_STS, ++ LPC_BMC_TRIG_WAKEUP_EVT_STS); ++ ++ reg = lpc_sio->reg_base + AST_LPC_ACPIB3B0; ++ regmap_write_bits(lpc_sio->regmap, reg, ++ LPC_BMC_TRIG_SCI_EVT_STS, ++ LPC_BMC_TRIG_SCI_EVT_STS); ++ } ++ ++ sio_data->data = sio_data->param; +} + -+typedef long (*sio_cmd_fn) (struct aspeed_lpc_sio *sio_dev, -+ struct sio_ioctl_data *sio_data); ++typedef void (*sio_cmd_fn) (struct aspeed_lpc_sio *sio_dev, ++ struct sio_ioctl_data *sio_data); ++ +static sio_cmd_fn sio_cmd_handle[SIO_MAX_CMD] = { -+ [SIO_GET_ACPI_STATE] = sio_get_acpi_state, -+ [SIO_GET_PWRGD_STATUS] = sio_get_pwrgd_status, -+ [SIO_GET_ONCTL_STATUS] = sio_get_onctl_status, -+ [SIO_SET_ONCTL_GPIO] = sio_set_onctl_gpio, -+ [SIO_GET_PWRBTN_OVERRIDE] = sio_get_pwrbtn_override, -+ [SIO_GET_PFAIL_STATUS] = sio_get_pfail_status, ++ [SIO_GET_ACPI_STATE] = sio_get_acpi_state, ++ [SIO_GET_PWRGD_STATUS] = sio_get_pwrgd_status, ++ [SIO_GET_ONCTL_STATUS] = sio_get_onctl_status, ++ [SIO_SET_ONCTL_GPIO] = sio_set_onctl_gpio, ++ [SIO_GET_PWRBTN_OVERRIDE] = sio_get_pwrbtn_override, ++ [SIO_GET_PFAIL_STATUS] = sio_get_pfail_status, ++ [SIO_SET_BMC_SCI_EVENT] = sio_set_bmc_sci_event, +}; + +static long aspeed_lpc_sio_ioctl(struct file *file, unsigned int cmd, -+ unsigned long param) ++ unsigned long param) +{ + struct aspeed_lpc_sio *lpc_sio = file_aspeed_lpc_sio(file); -+ long ret; -+ sio_cmd_fn cmd_fn; + struct sio_ioctl_data sio_data; -+ ++ sio_cmd_fn cmd_fn; ++ long ret; + + if (copy_from_user(&sio_data, (void __user *)param, sizeof(sio_data))) + return -EFAULT; @@ -447,18 +399,14 @@ index 000000000000..c717a3182320 + return -EINVAL; + + cmd_fn = sio_cmd_handle[sio_data.sio_cmd]; -+ if (cmd_fn == NULL) ++ if (!cmd_fn) + return -EINVAL; + + if (down_interruptible(&lpc_sio->lock) != 0) + return -ERESTARTSYS; + -+ ret = cmd_fn(lpc_sio, &sio_data); -+ if (ret == 0) { -+ if (copy_to_user((void __user *)param, &sio_data, -+ sizeof(sio_data))) -+ ret = -EFAULT; -+ } ++ cmd_fn(lpc_sio, &sio_data); ++ ret = copy_to_user((void __user *)param, &sio_data, sizeof(sio_data)); + + up(&lpc_sio->lock); + @@ -475,7 +423,8 @@ index 000000000000..c717a3182320 +{ + struct aspeed_lpc_sio *lpc_sio; + struct device *dev; -+ int rc; ++ u32 val; ++ int ret; + + dev = &pdev->dev; + @@ -485,40 +434,51 @@ index 000000000000..c717a3182320 + + dev_set_drvdata(&pdev->dev, lpc_sio); + -+ rc = of_property_read_u32(dev->of_node, "reg", &lpc_sio->reg_base); -+ if (rc) { ++ ret = of_property_read_u32(dev->of_node, "reg", &lpc_sio->reg_base); ++ if (ret) { + dev_err(dev, "Couldn't read reg device-tree property\n"); -+ return rc; ++ return ret; + } + -+ lpc_sio->regmap = syscon_node_to_regmap( -+ pdev->dev.parent->of_node); ++ lpc_sio->regmap = syscon_node_to_regmap(pdev->dev.parent->of_node); + if (IS_ERR(lpc_sio->regmap)) { + dev_err(dev, "Couldn't get regmap\n"); + return -ENODEV; + } + ++ /* ++ * We check that the regmap works on this very first access, ++ * but as this is an MMIO-backed regmap, subsequent regmap ++ * access is not going to fail and we skip error checks from ++ * this point. ++ */ ++ ret = regmap_read(lpc_sio->regmap, AST_LPC_SWCR0300, &val); ++ if (ret) { ++ dev_err(dev, "failed to read regmap\n"); ++ return ret; ++ } ++ + sema_init(&lpc_sio->lock, 1); + + lpc_sio->clk = devm_clk_get(dev, NULL); + if (IS_ERR(lpc_sio->clk)) { -+ rc = PTR_ERR(lpc_sio->clk); -+ if (rc != -EPROBE_DEFER) ++ ret = PTR_ERR(lpc_sio->clk); ++ if (ret != -EPROBE_DEFER) + dev_err(dev, "couldn't get clock\n"); -+ return rc; ++ return ret; + } -+ rc = clk_prepare_enable(lpc_sio->clk); -+ if (rc) { ++ ret = clk_prepare_enable(lpc_sio->clk); ++ if (ret) { + dev_err(dev, "couldn't enable clock\n"); -+ return rc; ++ return ret; + } + + lpc_sio->miscdev.minor = MISC_DYNAMIC_MINOR; + lpc_sio->miscdev.name = DEVICE_NAME; + lpc_sio->miscdev.fops = &aspeed_lpc_sio_fops; + lpc_sio->miscdev.parent = dev; -+ rc = misc_register(&lpc_sio->miscdev); -+ if (rc) { ++ ret = misc_register(&lpc_sio->miscdev); ++ if (ret) { + dev_err(dev, "Unable to register device\n"); + goto err; + } @@ -531,7 +491,7 @@ index 000000000000..c717a3182320 +err: + clk_disable_unprepare(lpc_sio->clk); + -+ return rc; ++ return ret; +} + +static int aspeed_lpc_sio_remove(struct platform_device *pdev) @@ -551,25 +511,25 @@ index 000000000000..c717a3182320 +MODULE_DEVICE_TABLE(of, aspeed_lpc_sio_match); + +static struct platform_driver aspeed_lpc_sio_driver = { -+ .driver = { ++ .driver = { + .name = SOC_NAME "-" DEVICE_NAME, -+ .of_match_table = aspeed_lpc_sio_match, ++ .of_match_table = of_match_ptr(aspeed_lpc_sio_match), + }, -+ .probe = aspeed_lpc_sio_probe, -+ .remove = aspeed_lpc_sio_remove, ++ .probe = aspeed_lpc_sio_probe, ++ .remove = aspeed_lpc_sio_remove, +}; +module_platform_driver(aspeed_lpc_sio_driver); + -+MODULE_LICENSE("GPL"); ++MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Ryan Chen "); +MODULE_AUTHOR("Yong Li "); +MODULE_DESCRIPTION("ASPEED AST LPC SIO device driver"); diff --git a/include/uapi/linux/aspeed-lpc-sio.h b/include/uapi/linux/aspeed-lpc-sio.h new file mode 100644 -index 000000000000..5dc1efd4a426 +index 000000000000..acf89a7d2b4a --- /dev/null +++ b/include/uapi/linux/aspeed-lpc-sio.h -@@ -0,0 +1,44 @@ +@@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012-2020 ASPEED Technology Inc. + * Copyright (c) 2017 Intel Corporation @@ -600,6 +560,7 @@ index 000000000000..5dc1efd4a426 + SIO_SET_ONCTL_GPIO, + SIO_GET_PWRBTN_OVERRIDE, + SIO_GET_PFAIL_STATUS, /* Start from AC Loss */ ++ SIO_SET_BMC_SCI_EVENT, + + SIO_MAX_CMD +}; diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0022-Add-AST2500-eSPI-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0022-Add-AST2500-eSPI-driver.patch index 490104cda..64059b1da 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0022-Add-AST2500-eSPI-driver.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0022-Add-AST2500-eSPI-driver.patch @@ -1,4 +1,4 @@ -From 1d0c60f1aa8b7b25d8d0d6f6f6443d307d543600 Mon Sep 17 00:00:00 2001 +From 34308f4078361987adfb854bdc6876abdaf323cb Mon Sep 17 00:00:00 2001 From: Haiyue Wang Date: Sat, 24 Feb 2018 11:12:32 +0800 Subject: [PATCH] Add AST2500 eSPI driver @@ -26,11 +26,12 @@ Signed-off-by: Vernon Mauery .../devicetree/bindings/misc/aspeed,espi-slave.txt | 20 + Documentation/misc-devices/espi-slave.rst | 118 ++++++ arch/arm/boot/dts/aspeed-g5.dtsi | 4 + - arch/arm/boot/dts/aspeed-g6.dtsi | 12 + + arch/arm/boot/dts/aspeed-g6.dtsi | 14 + drivers/misc/Kconfig | 8 + drivers/misc/Makefile | 1 + - drivers/misc/aspeed-espi-slave.c | 421 +++++++++++++++++++++ - 7 files changed, 584 insertions(+) + drivers/misc/aspeed-espi-slave.c | 468 +++++++++++++++++++++ + include/dt-bindings/clock/ast2600-clock.h | 1 + + 8 files changed, 634 insertions(+) create mode 100644 Documentation/devicetree/bindings/misc/aspeed,espi-slave.txt create mode 100644 Documentation/misc-devices/espi-slave.rst create mode 100644 drivers/misc/aspeed-espi-slave.c @@ -208,7 +209,7 @@ index c15be82c3a9d..bd2037e52a94 100644 lpc: lpc@1e789000 { diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi -index 459070693aba..e4c1ab3d274e 100644 +index 62d101dc6926..753770912f0a 100644 --- a/arch/arm/boot/dts/aspeed-g6.dtsi +++ b/arch/arm/boot/dts/aspeed-g6.dtsi @@ -3,6 +3,7 @@ @@ -219,7 +220,7 @@ index 459070693aba..e4c1ab3d274e 100644 / { model = "Aspeed BMC"; -@@ -651,6 +652,17 @@ +@@ -674,6 +675,19 @@ status = "disabled"; }; @@ -230,8 +231,10 @@ index 459070693aba..e4c1ab3d274e 100644 + <&gpio0 ASPEED_GPIO(W, 7) IRQ_TYPE_EDGE_FALLING>; + status = "disabled"; + clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>; ++ resets = <&syscon ASPEED_RESET_ESPI>; + pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_espi_default>; ++ pinctrl-0 = <&pinctrl_espi_default>, ++ <&pinctrl_espialt_default>; + }; + i2c: bus@1e78a000 { @@ -270,10 +273,10 @@ index b9e6d4c3e906..53864687e8fd 100644 obj-y += cardreader/ diff --git a/drivers/misc/aspeed-espi-slave.c b/drivers/misc/aspeed-espi-slave.c new file mode 100644 -index 000000000000..d70332d1fef3 +index 000000000000..87bc81948694 --- /dev/null +++ b/drivers/misc/aspeed-espi-slave.c -@@ -0,0 +1,421 @@ +@@ -0,0 +1,468 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2015-2019, Intel Corporation. + @@ -286,6 +289,7 @@ index 000000000000..d70332d1fef3 +#include +#include +#include ++#include +#include +#include +#include @@ -361,7 +365,9 @@ index 000000000000..d70332d1fef3 + struct regmap *map; + struct clk *clk; + struct device *dev; ++ struct reset_control *reset; + int irq; ++ int rst_irq; + + /* for PLTRST_N signal monitoring interface */ + struct miscdevice pltrstn_miscdev; @@ -469,11 +475,17 @@ index 000000000000..d70332d1fef3 + } + + if (sts & ASPEED_ESPI_HW_RESET) { ++ if (priv->rst_irq < 0) { ++ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL, ++ ASPEED_ESPI_CTRL_SW_RESET, 0); ++ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL, ++ ASPEED_ESPI_CTRL_SW_RESET, ++ ASPEED_ESPI_CTRL_SW_RESET); ++ } ++ + regmap_write_bits(priv->map, ASPEED_ESPI_CTRL, -+ ASPEED_ESPI_CTRL_SW_RESET, 0); -+ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL, -+ ASPEED_ESPI_CTRL_SW_RESET, -+ ASPEED_ESPI_CTRL_SW_RESET); ++ ASPEED_ESPI_CTRL_OOB_CHRDY, ++ ASPEED_ESPI_CTRL_OOB_CHRDY); + aspeed_espi_boot_ack(priv); + sts_handled |= ASPEED_ESPI_HW_RESET; + } @@ -504,8 +516,26 @@ index 000000000000..d70332d1fef3 + ASPEED_ESPI_SYSEVT1_INT_MASK); + + regmap_write(priv->map, ASPEED_ESPI_INT_EN, ASPEED_ESPI_INT_MASK); ++} + -+ aspeed_espi_boot_ack(priv); ++static irqreturn_t aspeed_espi_reset_isr(int irq, void *arg) ++{ ++ struct aspeed_espi *priv = arg; ++ ++ reset_control_assert(priv->reset); ++ reset_control_deassert(priv->reset); ++ ++ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL, ++ ASPEED_ESPI_CTRL_SW_RESET, 0); ++ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL, ++ ASPEED_ESPI_CTRL_SW_RESET, ASPEED_ESPI_CTRL_SW_RESET); ++ ++ regmap_write_bits(priv->map, ASPEED_ESPI_CTRL, ++ ASPEED_ESPI_CTRL_OOB_CHRDY, 0); ++ ++ aspeed_espi_config_irq(priv); ++ ++ return IRQ_HANDLED; +} + +static inline struct aspeed_espi *to_aspeed_espi(struct file *filp) @@ -610,13 +640,30 @@ index 000000000000..d70332d1fef3 + if (priv->irq < 0) + return priv->irq; + -+ aspeed_espi_config_irq(priv); -+ + ret = devm_request_irq(&pdev->dev, priv->irq, aspeed_espi_irq, 0, + "aspeed-espi-irq", priv); + if (ret) + return ret; + ++ if (of_device_is_compatible(pdev->dev.of_node, ++ "aspeed,ast2600-espi-slave")) { ++ priv->rst_irq = platform_get_irq(pdev, 1); ++ if (priv->rst_irq < 0) ++ return priv->rst_irq; ++ ++ ret = devm_request_irq(&pdev->dev, priv->rst_irq, ++ aspeed_espi_reset_isr, 0, ++ "aspeed-espi-rst-irq", priv); ++ if (ret) ++ return ret; ++ ++ priv->reset = devm_reset_control_get(&pdev->dev, NULL); ++ if (IS_ERR(priv->reset)) ++ return PTR_ERR(priv->reset); ++ } else { ++ priv->rst_irq = -ENOTSUPP; ++ } ++ + priv->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); @@ -654,6 +701,9 @@ index 000000000000..d70332d1fef3 + goto err_clk_disable_out; + } + ++ aspeed_espi_config_irq(priv); ++ aspeed_espi_boot_ack(priv); ++ + dev_info(&pdev->dev, "eSPI registered, irq %d\n", priv->irq); + + return 0; @@ -695,6 +745,18 @@ index 000000000000..d70332d1fef3 +MODULE_AUTHOR("Jae Hyun Yoo "); +MODULE_DESCRIPTION("Aspeed eSPI driver"); +MODULE_LICENSE("GPL v2"); +diff --git a/include/dt-bindings/clock/ast2600-clock.h b/include/dt-bindings/clock/ast2600-clock.h +index 3d90582a813f..1e18364de03d 100644 +--- a/include/dt-bindings/clock/ast2600-clock.h ++++ b/include/dt-bindings/clock/ast2600-clock.h +@@ -104,6 +104,7 @@ + #define ASPEED_RESET_PECI 36 + #define ASPEED_RESET_MII 35 + #define ASPEED_RESET_I2C 34 ++#define ASPEED_RESET_ESPI 32 + #define ASPEED_RESET_H2X 31 + #define ASPEED_RESET_GP_MCU 30 + #define ASPEED_RESET_DP_MCU 29 -- 2.7.4 diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0061-i2c-aspeed-add-buffer-mode-transfer-support.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0061-i2c-aspeed-add-buffer-mode-transfer-support.patch index 24032087b..fbf422a35 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0061-i2c-aspeed-add-buffer-mode-transfer-support.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0061-i2c-aspeed-add-buffer-mode-transfer-support.patch @@ -1,4 +1,4 @@ -From fcee7b9515140486ad8c58beedf88cf12cd09b8b Mon Sep 17 00:00:00 2001 +From b8d7d0f3513abdf014345b240a79d23c63409c4c Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo Date: Tue, 11 Jun 2019 15:07:08 -0700 Subject: [PATCH] i2c: aspeed: add buffer mode transfer support @@ -31,11 +31,11 @@ It provides buffer based master and slave data transfer. Signed-off-by: Jae Hyun Yoo --- .../devicetree/bindings/i2c/i2c-aspeed.txt | 40 ++- - arch/arm/boot/dts/aspeed-g4.dtsi | 47 ++-- - arch/arm/boot/dts/aspeed-g5.dtsi | 47 ++-- - arch/arm/boot/dts/aspeed-g6.dtsi | 32 +-- - drivers/i2c/busses/i2c-aspeed.c | 294 ++++++++++++++++++--- - 5 files changed, 365 insertions(+), 95 deletions(-) + arch/arm/boot/dts/aspeed-g4.dtsi | 47 +-- + arch/arm/boot/dts/aspeed-g5.dtsi | 47 +-- + arch/arm/boot/dts/aspeed-g6.dtsi | 32 +- + drivers/i2c/busses/i2c-aspeed.c | 376 +++++++++++++++++++-- + 5 files changed, 451 insertions(+), 91 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt index 7da7e813b2b0..0ff3539cee95 100644 @@ -422,10 +422,10 @@ index eb1f9c9d9cca..51593a0a8a23 100644 clocks = <&syscon ASPEED_CLK_APB>; resets = <&syscon ASPEED_RESET_I2C>; diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi -index 0e35c4598df5..eeace4b7b725 100644 +index f92a2aa999d1..3ef312543269 100644 --- a/arch/arm/boot/dts/aspeed-g6.dtsi +++ b/arch/arm/boot/dts/aspeed-g6.dtsi -@@ -713,7 +713,7 @@ +@@ -712,7 +712,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -434,7 +434,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -728,7 +728,7 @@ +@@ -727,7 +727,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -443,7 +443,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -743,7 +743,7 @@ +@@ -742,7 +742,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -452,7 +452,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -758,7 +758,7 @@ +@@ -757,7 +757,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -461,7 +461,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -773,7 +773,7 @@ +@@ -772,7 +772,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -470,7 +470,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -788,7 +788,7 @@ +@@ -787,7 +787,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -479,7 +479,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -803,7 +803,7 @@ +@@ -802,7 +802,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -488,7 +488,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -818,7 +818,7 @@ +@@ -817,7 +817,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -497,7 +497,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -833,7 +833,7 @@ +@@ -832,7 +832,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -506,7 +506,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -848,7 +848,7 @@ +@@ -847,7 +847,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -515,7 +515,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -863,7 +863,7 @@ +@@ -862,7 +862,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -524,7 +524,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -878,7 +878,7 @@ +@@ -877,7 +877,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -533,7 +533,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -893,7 +893,7 @@ +@@ -892,7 +892,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -542,7 +542,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -908,7 +908,7 @@ +@@ -907,7 +907,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -551,7 +551,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -923,7 +923,7 @@ +@@ -922,7 +922,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -560,7 +560,7 @@ index 0e35c4598df5..eeace4b7b725 100644 compatible = "aspeed,ast2600-i2c-bus"; clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; -@@ -938,7 +938,7 @@ +@@ -937,7 +937,7 @@ #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; @@ -570,7 +570,7 @@ index 0e35c4598df5..eeace4b7b725 100644 clocks = <&syscon ASPEED_CLK_APB2>; resets = <&syscon ASPEED_RESET_I2C>; diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index 7becfcd67142..1b338492c68a 100644 +index 7becfcd67142..bf72e151d11f 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -7,6 +7,7 @@ @@ -653,220 +653,338 @@ index 7becfcd67142..1b338492c68a 100644 bool multi_master; + /* Buffer mode */ + void __iomem *buf_base; -+ size_t buf_size; + u8 buf_offset; + u8 buf_page; ++ size_t buf_size; #if IS_ENABLED(CONFIG_I2C_SLAVE) struct i2c_client *slave; enum aspeed_i2c_slave_state slave_state; -@@ -259,6 +281,7 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) +@@ -255,6 +277,77 @@ static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus) + } + + #if IS_ENABLED(CONFIG_I2C_SLAVE) ++static inline void ++aspeed_i2c_slave_handle_rx_done(struct aspeed_i2c_bus *bus, u32 irq_status, ++ u8 *value) ++{ ++ if (bus->buf_base && ++ bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && ++ !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP)) ++ *value = readb(bus->buf_base); ++ else ++ *value = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8; ++} ++ ++static inline void ++aspeed_i2c_slave_handle_normal_stop(struct aspeed_i2c_bus *bus, u32 irq_status, ++ u8 *value) ++{ ++ int i, len; ++ ++ if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && ++ irq_status & ASPEED_I2CD_INTR_RX_DONE) { ++ if (bus->buf_base) { ++ len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, ++ readl(bus->base + ++ ASPEED_I2C_BUF_CTRL_REG)); ++ for (i = 0; i < len; i++) { ++ *value = readb(bus->buf_base + i); ++ i2c_slave_event(bus->slave, ++ I2C_SLAVE_WRITE_RECEIVED, ++ value); ++ } ++ } ++ } ++} ++ ++static inline void ++aspeed_i2c_slave_handle_write_requested(struct aspeed_i2c_bus *bus, u8 *value) ++{ ++ if (bus->buf_base) { ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, ++ bus->buf_size - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ writel(ASPEED_I2CD_RX_BUFF_ENABLE, ++ bus->base + ASPEED_I2C_CMD_REG); ++ } ++} ++ ++static inline void ++aspeed_i2c_slave_handle_write_received(struct aspeed_i2c_bus *bus, u8 *value) ++{ ++ int i, len; ++ ++ if (bus->buf_base) { ++ len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, ++ readl(bus->base + ++ ASPEED_I2C_BUF_CTRL_REG)); ++ for (i = 1; i < len; i++) { ++ *value = readb(bus->buf_base + i); ++ i2c_slave_event(bus->slave, I2C_SLAVE_WRITE_RECEIVED, ++ value); ++ } ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, ++ bus->buf_size - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ writel(ASPEED_I2CD_RX_BUFF_ENABLE, ++ bus->base + ASPEED_I2C_CMD_REG); ++ } ++} ++ + static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) { u32 command, irq_handled = 0; - struct i2c_client *slave = bus->slave; -+ int i, len; - u8 value; - - if (!slave) -@@ -281,7 +304,12 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) +@@ -281,7 +374,7 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) /* Slave was sent something. */ if (irq_status & ASPEED_I2CD_INTR_RX_DONE) { - value = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8; -+ if (bus->buf_base && -+ bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && -+ !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP)) -+ value = readb(bus->buf_base); -+ else -+ value = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8; ++ aspeed_i2c_slave_handle_rx_done(bus, irq_status, &value); /* Handle address frame. */ if (bus->slave_state == ASPEED_I2C_SLAVE_START) { if (value & 0x1) -@@ -296,6 +324,20 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) +@@ -296,9 +389,11 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) /* Slave was asked to stop. */ if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) { -+ if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && -+ irq_status & ASPEED_I2CD_INTR_RX_DONE) { -+ if (bus->buf_base) { -+ len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, -+ readl(bus->base + -+ ASPEED_I2C_BUF_CTRL_REG)); -+ for (i = 0; i < len; i++) { -+ value = readb(bus->buf_base + i); -+ i2c_slave_event(slave, -+ I2C_SLAVE_WRITE_RECEIVED, -+ &value); -+ } -+ } -+ } ++ aspeed_i2c_slave_handle_normal_stop(bus, irq_status, &value); irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP; bus->slave_state = ASPEED_I2C_SLAVE_STOP; } -@@ -328,9 +370,36 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) ++ + if (irq_status & ASPEED_I2CD_INTR_TX_NAK && + bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) { + irq_handled |= ASPEED_I2CD_INTR_TX_NAK; +@@ -328,9 +423,11 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) case ASPEED_I2C_SLAVE_WRITE_REQUESTED: bus->slave_state = ASPEED_I2C_SLAVE_WRITE_RECEIVED; i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value); -+ if (bus->buf_base) { -+ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, -+ bus->buf_size - 1) | -+ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -+ bus->buf_offset), -+ bus->base + ASPEED_I2C_BUF_CTRL_REG); -+ writel(ASPEED_I2CD_RX_BUFF_ENABLE, -+ bus->base + ASPEED_I2C_CMD_REG); -+ } ++ aspeed_i2c_slave_handle_write_requested(bus, &value); break; case ASPEED_I2C_SLAVE_WRITE_RECEIVED: i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value); -+ if (bus->buf_base) { -+ len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, -+ readl(bus->base + -+ ASPEED_I2C_BUF_CTRL_REG)); -+ for (i = 1; i < len; i++) { -+ value = readb(bus->buf_base + i); -+ i2c_slave_event(slave, -+ I2C_SLAVE_WRITE_RECEIVED, -+ &value); -+ } -+ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, -+ bus->buf_size - 1) | -+ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -+ bus->buf_offset), -+ bus->base + ASPEED_I2C_BUF_CTRL_REG); -+ writel(ASPEED_I2CD_RX_BUFF_ENABLE, -+ bus->base + ASPEED_I2C_CMD_REG); -+ } ++ aspeed_i2c_slave_handle_write_received(bus, &value); break; case ASPEED_I2C_SLAVE_STOP: i2c_slave_event(slave, I2C_SLAVE_STOP, &value); -@@ -356,6 +425,8 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) +@@ -350,12 +447,76 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + } + #endif /* CONFIG_I2C_SLAVE */ + ++static inline u32 ++aspeed_i2c_prepare_rx_buf(struct aspeed_i2c_bus *bus, struct i2c_msg *msg) ++{ ++ u32 command = 0; ++ int len; ++ ++ if (msg->len > bus->buf_size) { ++ len = bus->buf_size; ++ } else { ++ len = msg->len; ++ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; ++ } ++ ++ if (bus->buf_base) { ++ command |= ASPEED_I2CD_RX_BUFF_ENABLE; ++ ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, len - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ } ++ ++ return command; ++} ++ ++static inline u32 ++aspeed_i2c_prepare_tx_buf(struct aspeed_i2c_bus *bus, struct i2c_msg *msg) ++{ ++ u8 slave_addr = i2c_8bit_addr_from_msg(msg); ++ u32 command = 0; ++ int len; ++ ++ if (msg->len + 1 > bus->buf_size) ++ len = bus->buf_size; ++ else ++ len = msg->len + 1; ++ ++ if (bus->buf_base) { ++ u8 wbuf[4]; ++ int i; ++ ++ command |= ASPEED_I2CD_TX_BUFF_ENABLE; ++ ++ /* ++ * Yeah, it looks bad but byte writing on remapped I2C SRAM ++ * causes corruption so use this way to make dword writings. ++ */ ++ wbuf[0] = slave_addr; ++ for (i = 1; i < len; i++) { ++ wbuf[i % 4] = msg->buf[i - 1]; ++ if (i % 4 == 3) ++ writel(*(u32 *)wbuf, bus->buf_base + i - 3); ++ } ++ if (--i % 4 != 3) ++ writel(*(u32 *)wbuf, bus->buf_base + i - (i % 4)); ++ ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, len - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ } ++ ++ bus->buf_index = len - 1; ++ ++ return command; ++} ++ + /* precondition: bus.lock has been acquired. */ + static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) + { u32 command = ASPEED_I2CD_M_START_CMD | ASPEED_I2CD_M_TX_CMD; struct i2c_msg *msg = &bus->msgs[bus->msgs_index]; - u8 slave_addr = i2c_8bit_addr_from_msg(msg); -+ u8 wbuf[4]; -+ int len; +- u8 slave_addr = i2c_8bit_addr_from_msg(msg); #if IS_ENABLED(CONFIG_I2C_SLAVE) /* -@@ -374,12 +445,66 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) +@@ -374,12 +535,21 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) if (msg->flags & I2C_M_RD) { command |= ASPEED_I2CD_M_RX_CMD; - /* Need to let the hardware know to NACK after RX. */ - if (msg->len == 1 && !(msg->flags & I2C_M_RECV_LEN)) - command |= ASPEED_I2CD_M_S_RX_CMD_LAST; ++ if (!(msg->flags & I2C_M_RECV_LEN)) { ++ if (msg->len && bus->buf_base) ++ command |= aspeed_i2c_prepare_rx_buf(bus, msg); + -+ if (bus->buf_base && !(msg->flags & I2C_M_RECV_LEN)) { -+ command |= ASPEED_I2CD_RX_BUFF_ENABLE; -+ -+ if (msg->len > bus->buf_size) { -+ len = bus->buf_size; -+ } else { -+ len = msg->len; -+ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; -+ } -+ -+ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, -+ len - 1) | -+ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -+ bus->buf_offset), -+ bus->base + ASPEED_I2C_BUF_CTRL_REG); -+ } else { + /* Need to let the hardware know to NACK after RX. */ -+ if (msg->len == 1 && !(msg->flags & I2C_M_RECV_LEN)) ++ if (msg->len <= 1) + command |= ASPEED_I2CD_M_S_RX_CMD_LAST; + } -+ } else { -+ if (bus->buf_base) { -+ int i; -+ -+ command |= ASPEED_I2CD_TX_BUFF_ENABLE; -+ -+ if (msg->len + 1 > bus->buf_size) -+ len = bus->buf_size; -+ else -+ len = msg->len + 1; -+ -+ /* -+ * Yeah, it looks clumsy but byte writings on a remapped -+ * I2C SRAM cause corruptions so use this way to make -+ * dword writings. -+ */ -+ wbuf[0] = slave_addr; -+ for (i = 1; i < len; i++) { -+ wbuf[i % 4] = msg->buf[i - 1]; -+ if (i % 4 == 3) -+ writel(*(u32 *)wbuf, -+ bus->buf_base + i - 3); -+ } -+ if (--i % 4 != 3) -+ writel(*(u32 *)wbuf, -+ bus->buf_base + i - (i % 4)); -+ -+ bus->buf_index = len - 1; -+ -+ writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, -+ len - 1) | -+ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -+ bus->buf_offset), -+ bus->base + ASPEED_I2C_BUF_CTRL_REG); -+ } ++ } else if (msg->len && bus->buf_base) { ++ command |= aspeed_i2c_prepare_tx_buf(bus, msg); } - writel(slave_addr, bus->base + ASPEED_I2C_BYTE_BUF_REG); + if (!(command & ASPEED_I2CD_TX_BUFF_ENABLE)) -+ writel(slave_addr, bus->base + ASPEED_I2C_BYTE_BUF_REG); ++ writel(i2c_8bit_addr_from_msg(msg), ++ bus->base + ASPEED_I2C_BYTE_BUF_REG); writel(command, bus->base + ASPEED_I2C_CMD_REG); } -@@ -419,7 +544,7 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - u32 irq_handled = 0, command = 0; - struct i2c_msg *msg; - u8 recv_byte; -- int ret; -+ int ret, len; +@@ -414,6 +584,104 @@ static int aspeed_i2c_is_irq_error(u32 irq_status) + return 0; + } - if (irq_status & ASPEED_I2CD_INTR_BUS_RECOVER_DONE) { - bus->master_state = ASPEED_I2C_MASTER_INACTIVE; -@@ -522,11 +647,43 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - /* fall through */ - case ASPEED_I2C_MASTER_TX_FIRST: - if (bus->buf_index < msg->len) { -+ command = ASPEED_I2CD_M_TX_CMD; ++static inline u32 ++aspeed_i2c_master_handle_tx_first(struct aspeed_i2c_bus *bus, ++ struct i2c_msg *msg) ++{ ++ u32 command = 0; + -+ if (bus->buf_base) { -+ u8 wbuf[4]; -+ int i; ++ if (bus->buf_base) { ++ u8 wbuf[4]; ++ int len; ++ int i; + -+ command |= ASPEED_I2CD_TX_BUFF_ENABLE; ++ if (msg->len - bus->buf_index > bus->buf_size) ++ len = bus->buf_size; ++ else ++ len = msg->len - bus->buf_index; + -+ if (msg->len - bus->buf_index > bus->buf_size) -+ len = bus->buf_size; -+ else -+ len = msg->len - bus->buf_index; + -+ for (i = 0; i < len; i++) { -+ wbuf[i % 4] = msg->buf[bus->buf_index -+ + i]; -+ if (i % 4 == 3) -+ writel(*(u32 *)wbuf, -+ bus->buf_base + i - 3); -+ } -+ if (--i % 4 != 3) -+ writel(*(u32 *)wbuf, -+ bus->buf_base + i - (i % 4)); ++ command |= ASPEED_I2CD_TX_BUFF_ENABLE; + -+ bus->buf_index += len; ++ if (msg->len - bus->buf_index > bus->buf_size) ++ len = bus->buf_size; ++ else ++ len = msg->len - bus->buf_index; + -+ writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, -+ len - 1) | -+ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -+ bus->buf_offset), -+ bus->base + ASPEED_I2C_BUF_CTRL_REG); -+ } else { -+ writel(msg->buf[bus->buf_index++], -+ bus->base + ASPEED_I2C_BYTE_BUF_REG); -+ } ++ for (i = 0; i < len; i++) { ++ wbuf[i % 4] = msg->buf[bus->buf_index + i]; ++ if (i % 4 == 3) ++ writel(*(u32 *)wbuf, ++ bus->buf_base + i - 3); ++ } ++ if (--i % 4 != 3) ++ writel(*(u32 *)wbuf, ++ bus->buf_base + i - (i % 4)); ++ ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, ++ len - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ ++ bus->buf_index += len; ++ } else { ++ writel(msg->buf[bus->buf_index++], ++ bus->base + ASPEED_I2C_BYTE_BUF_REG); ++ } ++ ++ return command; ++} ++ ++static inline void ++aspeed_i2c_master_handle_rx(struct aspeed_i2c_bus *bus, struct i2c_msg *msg) ++{ ++ u8 recv_byte; ++ int len; ++ ++ if (bus->buf_base) { ++ len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, ++ readl(bus->base + ASPEED_I2C_BUF_CTRL_REG)); ++ memcpy_fromio(msg->buf + bus->buf_index, bus->buf_base, len); ++ bus->buf_index += len; ++ } else { ++ recv_byte = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8; ++ msg->buf[bus->buf_index++] = recv_byte; ++ } ++} ++ ++static inline u32 ++aspeed_i2c_master_handle_rx_next(struct aspeed_i2c_bus *bus, ++ struct i2c_msg *msg) ++{ ++ u32 command = 0; ++ ++ if (bus->buf_base) { ++ int len; ++ ++ if (msg->len - bus->buf_index > bus->buf_size) { ++ len = bus->buf_size; ++ } else { ++ len = msg->len - bus->buf_index; ++ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; ++ } ++ ++ command |= ASPEED_I2CD_RX_BUFF_ENABLE; ++ ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, ++ len - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, 0) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ } else { ++ if (bus->buf_index + 1 == msg->len) ++ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; ++ } ++ ++ return command; ++} ++ + static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + { + u32 irq_handled = 0, command = 0; +@@ -522,11 +790,10 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + /* fall through */ + case ASPEED_I2C_MASTER_TX_FIRST: + if (bus->buf_index < msg->len) { ++ command = ASPEED_I2CD_M_TX_CMD; ++ command |= aspeed_i2c_master_handle_tx_first(bus, msg); + writel(command, bus->base + ASPEED_I2C_CMD_REG); bus->master_state = ASPEED_I2C_MASTER_TX; - writel(msg->buf[bus->buf_index++], @@ -876,44 +994,28 @@ index 7becfcd67142..1b338492c68a 100644 } else { aspeed_i2c_next_msg_or_stop(bus); } -@@ -543,25 +700,56 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) +@@ -543,26 +810,26 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) } irq_handled |= ASPEED_I2CD_INTR_RX_DONE; - recv_byte = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8; - msg->buf[bus->buf_index++] = recv_byte; - -- if (msg->flags & I2C_M_RECV_LEN) { -- if (unlikely(recv_byte > I2C_SMBUS_BLOCK_MAX)) { -- bus->cmd_err = -EPROTO; -- aspeed_i2c_do_stop(bus); -- goto out_no_complete; -+ if (bus->buf_base && !(msg->flags & I2C_M_RECV_LEN)) { -+ len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, -+ readl(bus->base + -+ ASPEED_I2C_BUF_CTRL_REG)); -+ memcpy_fromio(msg->buf + bus->buf_index, -+ bus->buf_base, len); -+ bus->buf_index += len; -+ } else { -+ recv_byte = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) -+ >> 8; -+ msg->buf[bus->buf_index++] = recv_byte; -+ -+ if (msg->flags & I2C_M_RECV_LEN) { -+ if (unlikely(recv_byte > I2C_SMBUS_BLOCK_MAX)) { -+ bus->cmd_err = -EPROTO; -+ aspeed_i2c_do_stop(bus); -+ goto out_no_complete; -+ } -+ msg->len = recv_byte + -+ ((msg->flags & I2C_CLIENT_PEC) ? -+ 2 : 1); -+ msg->flags &= ~I2C_M_RECV_LEN; + if (msg->flags & I2C_M_RECV_LEN) { ++ recv_byte = readl(bus->base + ++ ASPEED_I2C_BYTE_BUF_REG) >> 8; + if (unlikely(recv_byte > I2C_SMBUS_BLOCK_MAX)) { + bus->cmd_err = -EPROTO; + aspeed_i2c_do_stop(bus); + goto out_no_complete; } - msg->len = recv_byte + - ((msg->flags & I2C_CLIENT_PEC) ? 2 : 1); -- msg->flags &= ~I2C_M_RECV_LEN; ++ msg->len = recv_byte + ((msg->flags & I2C_CLIENT_PEC) ? ++ 2 : 1); + msg->flags &= ~I2C_M_RECV_LEN; ++ } else if (msg->len) { ++ aspeed_i2c_master_handle_rx(bus, msg); } if (bus->buf_index < msg->len) { @@ -921,33 +1023,13 @@ index 7becfcd67142..1b338492c68a 100644 command = ASPEED_I2CD_M_RX_CMD; - if (bus->buf_index + 1 == msg->len) - command |= ASPEED_I2CD_M_S_RX_CMD_LAST; -+ bus->master_state = ASPEED_I2C_MASTER_RX; -+ if (bus->buf_base) { -+ command |= ASPEED_I2CD_RX_BUFF_ENABLE; -+ -+ if (msg->len - bus->buf_index > -+ bus->buf_size) { -+ len = bus->buf_size; -+ } else { -+ len = msg->len - bus->buf_index; -+ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; -+ } -+ -+ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, -+ len - 1) | -+ FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, -+ 0) | -+ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -+ bus->buf_offset), -+ bus->base + ASPEED_I2C_BUF_CTRL_REG); -+ } else { -+ if (bus->buf_index + 1 == msg->len) -+ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; -+ } ++ command |= aspeed_i2c_master_handle_rx_next(bus, msg); writel(command, bus->base + ASPEED_I2C_CMD_REG); ++ bus->master_state = ASPEED_I2C_MASTER_RX; } else { aspeed_i2c_next_msg_or_stop(bus); -@@ -924,6 +1112,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus, + } +@@ -924,6 +1191,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus, if (ret < 0) return ret; @@ -957,34 +1039,24 @@ index 7becfcd67142..1b338492c68a 100644 if (of_property_read_bool(pdev->dev.of_node, "multi-master")) bus->multi_master = true; else -@@ -985,16 +1176,15 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) - { - const struct of_device_id *match; - struct aspeed_i2c_bus *bus; -+ bool sram_enabled = true; - struct clk *parent_clk; -- struct resource *res; - int irq, ret; - - bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); - if (!bus) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- bus->base = devm_ioremap_resource(&pdev->dev, res); -+ bus->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(bus->base)) - return PTR_ERR(bus->base); - -@@ -1028,6 +1218,42 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) - bus->get_clk_reg_val = (u32 (*)(struct device *, u32)) - match->data; +@@ -964,6 +1234,52 @@ static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus) + return ret; + } -+ /* Enable I2C SRAM in case of AST2500 */ ++static void aspeed_i2c_set_xfer_mode(struct aspeed_i2c_bus *bus) ++{ ++ struct platform_device *pdev = to_platform_device(bus->dev); ++ bool sram_enabled = true; ++ int ret; ++ ++ /* ++ * Enable I2C SRAM in case of AST2500. ++ * SRAM is enabled by default in AST2400 and AST2600. ++ */ + if (of_device_is_compatible(pdev->dev.of_node, + "aspeed,ast2500-i2c-bus")) { -+ struct regmap *gr_regmap = syscon_regmap_lookup_by_compatible( -+ "aspeed,ast2500-i2c-gr"); ++ struct regmap *gr_regmap = syscon_regmap_lookup_by_compatible("aspeed,ast2500-i2c-gr"); ++ + if (IS_ERR(gr_regmap)) + ret = PTR_ERR(gr_regmap); + else @@ -1001,10 +1073,10 @@ index 7becfcd67142..1b338492c68a 100644 + struct resource *res = platform_get_resource(pdev, + IORESOURCE_MEM, 1); + -+ if (res) ++ if (res && resource_size(res) >= 2) + bus->buf_base = devm_ioremap_resource(&pdev->dev, res); + -+ if (!IS_ERR_OR_NULL(bus->buf_base) && resource_size(res) >= 2) { ++ if (!IS_ERR_OR_NULL(bus->buf_base)) { + bus->buf_size = resource_size(res); + if (of_device_is_compatible(pdev->dev.of_node, + "aspeed,ast2400-i2c-bus")) { @@ -1015,11 +1087,52 @@ index 7becfcd67142..1b338492c68a 100644 + } + } + } ++} ++ + static const struct of_device_id aspeed_i2c_bus_of_table[] = { + { + .compatible = "aspeed,ast2400-i2c-bus", +@@ -986,18 +1302,18 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) + const struct of_device_id *match; + struct aspeed_i2c_bus *bus; + struct clk *parent_clk; +- struct resource *res; + int irq, ret; + + bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); + if (!bus) + return -ENOMEM; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- bus->base = devm_ioremap_resource(&pdev->dev, res); ++ bus->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(bus->base)) + return PTR_ERR(bus->base); + ++ bus->dev = &pdev->dev; ++ + parent_clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(parent_clk)) + return PTR_ERR(parent_clk); +@@ -1028,6 +1344,8 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) + bus->get_clk_reg_val = (u32 (*)(struct device *, u32)) + match->data; + ++ aspeed_i2c_set_xfer_mode(bus); + /* Initialize the I2C adapter */ spin_lock_init(&bus->lock); init_completion(&bus->cmd_complete); -@@ -1063,8 +1289,8 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) +@@ -1038,8 +1356,6 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) + strlcpy(bus->adap.name, pdev->name, sizeof(bus->adap.name)); + i2c_set_adapdata(&bus->adap, bus); + +- bus->dev = &pdev->dev; +- + /* Clean up any left over interrupt state. */ + writel(0, bus->base + ASPEED_I2C_INTR_CTRL_REG); + writel(0xffffffff, bus->base + ASPEED_I2C_INTR_STS_REG); +@@ -1063,8 +1379,8 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) platform_set_drvdata(pdev, bus); diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-i2c-aspeed-add-DMA-mode-transfer-support.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-i2c-aspeed-add-DMA-mode-transfer-support.patch index a66e759e7..994c20b18 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-i2c-aspeed-add-DMA-mode-transfer-support.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0062-i2c-aspeed-add-DMA-mode-transfer-support.patch @@ -1,4 +1,4 @@ -From 0d237f4b5111aa192a1ae9aaee6e6779761906bc Mon Sep 17 00:00:00 2001 +From 5bf7a202eb0af455675a85a4f1bdad863fd8805d Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo Date: Tue, 18 Jun 2019 08:47:50 -0700 Subject: [PATCH] i2c: aspeed: add DMA mode transfer support @@ -15,9 +15,9 @@ use DMA mode. Signed-off-by: Jae Hyun Yoo --- - .../devicetree/bindings/i2c/i2c-aspeed.txt | 25 +++ - drivers/i2c/busses/i2c-aspeed.c | 231 +++++++++++++++++++-- - 2 files changed, 241 insertions(+), 15 deletions(-) + .../devicetree/bindings/i2c/i2c-aspeed.txt | 25 ++ + drivers/i2c/busses/i2c-aspeed.c | 253 +++++++++++++++++---- + 2 files changed, 234 insertions(+), 44 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt index 0ff3539cee95..d3f4a39f7ba6 100644 @@ -61,7 +61,7 @@ index 0ff3539cee95..d3f4a39f7ba6 100644 + }; }; diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index 1b338492c68a..8dc6723bfaaf 100644 +index bf72e151d11f..3c9e491cbe4e 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -10,6 +10,8 @@ @@ -106,242 +106,291 @@ index 1b338492c68a..8dc6723bfaaf 100644 enum aspeed_i2c_master_state { ASPEED_I2C_MASTER_INACTIVE, ASPEED_I2C_MASTER_PENDING, -@@ -185,6 +199,12 @@ struct aspeed_i2c_bus { - size_t buf_size; +@@ -184,6 +198,12 @@ struct aspeed_i2c_bus { + void __iomem *buf_base; u8 buf_offset; u8 buf_page; + /* DMA mode */ + struct dma_pool *dma_pool; + dma_addr_t dma_handle; + u8 *dma_buf; -+ size_t dma_buf_size; + size_t dma_len; ++ /* Buffer/DMA mode */ + size_t buf_size; #if IS_ENABLED(CONFIG_I2C_SLAVE) struct i2c_client *slave; - enum aspeed_i2c_slave_state slave_state; -@@ -304,9 +324,13 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - - /* Slave was sent something. */ - if (irq_status & ASPEED_I2CD_INTR_RX_DONE) { -- if (bus->buf_base && -+ if (bus->dma_buf && - bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && - !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP)) -+ value = bus->dma_buf[0]; -+ else if (bus->buf_base && -+ bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && -+ !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP)) - value = readb(bus->buf_base); - else - value = readl(bus->base + ASPEED_I2C_BYTE_BUF_REG) >> 8; -@@ -326,7 +350,18 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) { - if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && - irq_status & ASPEED_I2CD_INTR_RX_DONE) { -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ len = bus->dma_buf_size - -+ FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK, -+ readl(bus->base + -+ ASPEED_I2C_DMA_LEN_REG)); -+ for (i = 0; i < len; i++) { -+ value = bus->dma_buf[i]; -+ i2c_slave_event(slave, -+ I2C_SLAVE_WRITE_RECEIVED, -+ &value); -+ } -+ } else if (bus->buf_base) { - len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, - readl(bus->base + - ASPEED_I2C_BUF_CTRL_REG)); -@@ -370,7 +405,15 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - case ASPEED_I2C_SLAVE_WRITE_REQUESTED: - bus->slave_state = ASPEED_I2C_SLAVE_WRITE_RECEIVED; - i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value); -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, -+ bus->dma_buf_size), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ writel(ASPEED_I2CD_RX_DMA_ENABLE, -+ bus->base + ASPEED_I2C_CMD_REG); -+ } else if (bus->buf_base) { - writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, - bus->buf_size - 1) | - FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, -@@ -382,7 +425,25 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - break; - case ASPEED_I2C_SLAVE_WRITE_RECEIVED: - i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value); +@@ -281,7 +301,11 @@ static inline void + aspeed_i2c_slave_handle_rx_done(struct aspeed_i2c_bus *bus, u32 irq_status, + u8 *value) + { +- if (bus->buf_base && ++ if (bus->dma_buf && ++ bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && ++ !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP)) ++ *value = bus->dma_buf[0]; ++ else if (bus->buf_base && + bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && + !(irq_status & ASPEED_I2CD_INTR_NORMAL_STOP)) + *value = readb(bus->buf_base); +@@ -297,7 +321,18 @@ aspeed_i2c_slave_handle_normal_stop(struct aspeed_i2c_bus *bus, u32 irq_status, + + if (bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED && + irq_status & ASPEED_I2CD_INTR_RX_DONE) { - if (bus->buf_base) { + if (bus->dma_buf) { -+ len = bus->dma_buf_size - ++ len = bus->buf_size - + FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK, + readl(bus->base + + ASPEED_I2C_DMA_LEN_REG)); -+ for (i = 1; i < len; i++) { -+ value = bus->dma_buf[i]; -+ i2c_slave_event(slave, ++ for (i = 0; i < len; i++) { ++ *value = bus->dma_buf[i]; ++ i2c_slave_event(bus->slave, + I2C_SLAVE_WRITE_RECEIVED, -+ &value); ++ value); + } -+ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, -+ bus->dma_buf_size), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ writel(ASPEED_I2CD_RX_DMA_ENABLE, -+ bus->base + ASPEED_I2C_CMD_REG); + } else if (bus->buf_base) { len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, readl(bus->base + ASPEED_I2C_BUF_CTRL_REG)); -@@ -446,7 +507,23 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) - if (msg->flags & I2C_M_RD) { - command |= ASPEED_I2CD_M_RX_CMD; +@@ -314,7 +349,14 @@ aspeed_i2c_slave_handle_normal_stop(struct aspeed_i2c_bus *bus, u32 irq_status, + static inline void + aspeed_i2c_slave_handle_write_requested(struct aspeed_i2c_bus *bus, u8 *value) + { +- if (bus->buf_base) { ++ if (bus->dma_buf) { ++ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, ++ bus->base + ASPEED_I2C_DMA_ADDR_REG); ++ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, bus->buf_size), ++ bus->base + ASPEED_I2C_DMA_LEN_REG); ++ writel(ASPEED_I2CD_RX_DMA_ENABLE, ++ bus->base + ASPEED_I2C_CMD_REG); ++ } else if (bus->buf_base) { + writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, + bus->buf_size - 1) | + FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, +@@ -330,7 +372,23 @@ aspeed_i2c_slave_handle_write_received(struct aspeed_i2c_bus *bus, u8 *value) + { + int i, len; -- if (bus->buf_base && !(msg->flags & I2C_M_RECV_LEN)) { -+ if (bus->dma_buf && !(msg->flags & I2C_M_RECV_LEN)) { -+ command |= ASPEED_I2CD_RX_DMA_ENABLE; -+ -+ if (msg->len > bus->dma_buf_size) { -+ len = bus->dma_buf_size; -+ } else { -+ len = msg->len; -+ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; -+ } -+ -+ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, -+ len), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ bus->dma_len = len; -+ } else if (bus->buf_base && !(msg->flags & I2C_M_RECV_LEN)) { - command |= ASPEED_I2CD_RX_BUFF_ENABLE; +- if (bus->buf_base) { ++ if (bus->dma_buf) { ++ len = bus->buf_size - ++ FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK, ++ readl(bus->base + ++ ASPEED_I2C_DMA_LEN_REG)); ++ for (i = 1; i < len; i++) { ++ *value = bus->dma_buf[i]; ++ i2c_slave_event(bus->slave, I2C_SLAVE_WRITE_RECEIVED, ++ value); ++ } ++ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, ++ bus->base + ASPEED_I2C_DMA_ADDR_REG); ++ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, bus->buf_size), ++ bus->base + ASPEED_I2C_DMA_LEN_REG); ++ writel(ASPEED_I2CD_RX_DMA_ENABLE, ++ bus->base + ASPEED_I2C_CMD_REG); ++ } else if (bus->buf_base) { + len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, + readl(bus->base + + ASPEED_I2C_BUF_CTRL_REG)); +@@ -460,7 +518,15 @@ aspeed_i2c_prepare_rx_buf(struct aspeed_i2c_bus *bus, struct i2c_msg *msg) + command |= ASPEED_I2CD_M_S_RX_CMD_LAST; + } - if (msg->len > bus->buf_size) { -@@ -467,7 +544,26 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) - command |= ASPEED_I2CD_M_S_RX_CMD_LAST; - } - } else { -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ command |= ASPEED_I2CD_TX_DMA_ENABLE; -+ -+ if (msg->len + 1 > bus->dma_buf_size) -+ len = bus->dma_buf_size; -+ else -+ len = msg->len + 1; +- if (bus->buf_base) { ++ if (bus->dma_buf) { ++ command |= ASPEED_I2CD_RX_DMA_ENABLE; + -+ bus->dma_buf[0] = slave_addr; -+ memcpy(bus->dma_buf + 1, msg->buf, len); ++ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, ++ bus->base + ASPEED_I2C_DMA_ADDR_REG); ++ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len), ++ bus->base + ASPEED_I2C_DMA_LEN_REG); ++ bus->dma_len = len; ++ } else { + command |= ASPEED_I2CD_RX_BUFF_ENABLE; + + writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, len - 1) | +@@ -483,7 +549,18 @@ aspeed_i2c_prepare_tx_buf(struct aspeed_i2c_bus *bus, struct i2c_msg *msg) + else + len = msg->len + 1; + +- if (bus->buf_base) { ++ if (bus->dma_buf) { ++ command |= ASPEED_I2CD_TX_DMA_ENABLE; + -+ bus->buf_index = len - 1; ++ bus->dma_buf[0] = slave_addr; ++ memcpy(bus->dma_buf + 1, msg->buf, len); + -+ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, -+ len), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ bus->dma_len = len; -+ } else if (bus->buf_base) { - int i; ++ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, ++ bus->base + ASPEED_I2C_DMA_ADDR_REG); ++ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len), ++ bus->base + ASPEED_I2C_DMA_LEN_REG); ++ bus->dma_len = len; ++ } else { + u8 wbuf[4]; + int i; + +@@ -536,18 +613,19 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) + if (msg->flags & I2C_M_RD) { + command |= ASPEED_I2CD_M_RX_CMD; + if (!(msg->flags & I2C_M_RECV_LEN)) { +- if (msg->len && bus->buf_base) ++ if (msg->len && (bus->dma_buf || bus->buf_base)) + command |= aspeed_i2c_prepare_rx_buf(bus, msg); - command |= ASPEED_I2CD_TX_BUFF_ENABLE; -@@ -503,7 +599,8 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) + /* Need to let the hardware know to NACK after RX. */ + if (msg->len <= 1) + command |= ASPEED_I2CD_M_S_RX_CMD_LAST; } +- } else if (msg->len && bus->buf_base) { ++ } else if (msg->len && (bus->dma_buf || bus->buf_base)) { + command |= aspeed_i2c_prepare_tx_buf(bus, msg); } - if (!(command & ASPEED_I2CD_TX_BUFF_ENABLE)) + if (!(command & (ASPEED_I2CD_TX_BUFF_ENABLE | + ASPEED_I2CD_TX_DMA_ENABLE))) - writel(slave_addr, bus->base + ASPEED_I2C_BYTE_BUF_REG); + writel(i2c_8bit_addr_from_msg(msg), + bus->base + ASPEED_I2C_BYTE_BUF_REG); writel(command, bus->base + ASPEED_I2C_CMD_REG); - } -@@ -649,7 +746,28 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - if (bus->buf_index < msg->len) { - command = ASPEED_I2CD_M_TX_CMD; +@@ -590,39 +668,52 @@ aspeed_i2c_master_handle_tx_first(struct aspeed_i2c_bus *bus, + { + u32 command = 0; + +- if (bus->buf_base) { +- u8 wbuf[4]; ++ if (bus->dma_buf || bus->buf_base) { + int len; +- int i; -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ command |= ASPEED_I2CD_TX_DMA_ENABLE; + if (msg->len - bus->buf_index > bus->buf_size) + len = bus->buf_size; + else + len = msg->len - bus->buf_index; + ++ if (bus->dma_buf) { ++ command |= ASPEED_I2CD_TX_DMA_ENABLE; + +- command |= ASPEED_I2CD_TX_BUFF_ENABLE; ++ memcpy(bus->dma_buf, msg->buf + bus->buf_index, len); + +- if (msg->len - bus->buf_index > bus->buf_size) +- len = bus->buf_size; +- else +- len = msg->len - bus->buf_index; + +- for (i = 0; i < len; i++) { +- wbuf[i % 4] = msg->buf[bus->buf_index + i]; +- if (i % 4 == 3) ++ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, ++ bus->base + ASPEED_I2C_DMA_ADDR_REG); ++ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len), ++ bus->base + ASPEED_I2C_DMA_LEN_REG); ++ bus->dma_len = len; ++ } else { ++ u8 wbuf[4]; ++ int i; + -+ if (msg->len - bus->buf_index > -+ bus->dma_buf_size) -+ len = bus->dma_buf_size; -+ else -+ len = msg->len - bus->buf_index; ++ command |= ASPEED_I2CD_TX_BUFF_ENABLE; + -+ memcpy(bus->dma_buf, msg->buf + bus->buf_index, -+ len); ++ if (msg->len - bus->buf_index > bus->buf_size) ++ len = bus->buf_size; ++ else ++ len = msg->len - bus->buf_index; + -+ bus->buf_index += len; ++ for (i = 0; i < len; i++) { ++ wbuf[i % 4] = msg->buf[bus->buf_index + i]; ++ if (i % 4 == 3) ++ writel(*(u32 *)wbuf, ++ bus->buf_base + i - 3); ++ } ++ if (--i % 4 != 3) + writel(*(u32 *)wbuf, +- bus->buf_base + i - 3); +- } +- if (--i % 4 != 3) +- writel(*(u32 *)wbuf, +- bus->buf_base + i - (i % 4)); ++ bus->buf_base + i - (i % 4)); + +- writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, +- len - 1) | +- FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, +- bus->buf_offset), +- bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, ++ len - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ } + + bus->buf_index += len; + } else { +@@ -639,7 +730,14 @@ aspeed_i2c_master_handle_rx(struct aspeed_i2c_bus *bus, struct i2c_msg *msg) + u8 recv_byte; + int len; + +- if (bus->buf_base) { ++ if (bus->dma_buf) { ++ len = bus->dma_len - ++ FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK, ++ readl(bus->base + ASPEED_I2C_DMA_LEN_REG)); + -+ writel(bus->dma_handle & -+ ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, -+ len), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ bus->dma_len = len; -+ } else if (bus->buf_base) { - u8 wbuf[4]; - int i; - -@@ -700,7 +818,15 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) ++ memcpy(msg->buf + bus->buf_index, bus->dma_buf, len); ++ bus->buf_index += len; ++ } else if (bus->buf_base) { + len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, + readl(bus->base + ASPEED_I2C_BUF_CTRL_REG)); + memcpy_fromio(msg->buf + bus->buf_index, bus->buf_base, len); +@@ -656,7 +754,7 @@ aspeed_i2c_master_handle_rx_next(struct aspeed_i2c_bus *bus, + { + u32 command = 0; + +- if (bus->buf_base) { ++ if (bus->dma_buf || bus->buf_base) { + int len; + + if (msg->len - bus->buf_index > bus->buf_size) { +@@ -666,14 +764,24 @@ aspeed_i2c_master_handle_rx_next(struct aspeed_i2c_bus *bus, + command |= ASPEED_I2CD_M_S_RX_CMD_LAST; } - irq_handled |= ASPEED_I2CD_INTR_RX_DONE; -- if (bus->buf_base && !(msg->flags & I2C_M_RECV_LEN)) { -+ if (bus->dma_buf && !(msg->flags & I2C_M_RECV_LEN)) { -+ len = bus->dma_len - -+ FIELD_GET(ASPEED_I2CD_DMA_LEN_MASK, -+ readl(bus->base + -+ ASPEED_I2C_DMA_LEN_REG)); -+ -+ memcpy(msg->buf + bus->buf_index, bus->dma_buf, len); -+ bus->buf_index += len; -+ } else if (bus->buf_base && !(msg->flags & I2C_M_RECV_LEN)) { - len = FIELD_GET(ASPEED_I2CD_BUF_RX_COUNT_MASK, - readl(bus->base + - ASPEED_I2C_BUF_CTRL_REG)); -@@ -728,7 +854,25 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - if (bus->buf_index < msg->len) { - command = ASPEED_I2CD_M_RX_CMD; - bus->master_state = ASPEED_I2C_MASTER_RX; -- if (bus->buf_base) { -+ if (bus->dma_buf) { -+ command |= ASPEED_I2CD_RX_DMA_ENABLE; -+ -+ if (msg->len - bus->buf_index > -+ bus->dma_buf_size) { -+ len = bus->dma_buf_size; -+ } else { -+ len = msg->len - bus->buf_index; -+ command |= ASPEED_I2CD_M_S_RX_CMD_LAST; -+ } +- command |= ASPEED_I2CD_RX_BUFF_ENABLE; ++ if (bus->dma_buf) { ++ command |= ASPEED_I2CD_RX_DMA_ENABLE; + +- writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, +- len - 1) | +- FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, 0) | +- FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, +- bus->buf_offset), +- bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ writel(bus->dma_handle & ASPEED_I2CD_DMA_ADDR_MASK, ++ bus->base + ASPEED_I2C_DMA_ADDR_REG); ++ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, len), ++ bus->base + ASPEED_I2C_DMA_LEN_REG); ++ bus->dma_len = len; ++ } else { ++ command |= ASPEED_I2CD_RX_BUFF_ENABLE; + -+ writel(bus->dma_handle & -+ ASPEED_I2CD_DMA_ADDR_MASK, -+ bus->base + ASPEED_I2C_DMA_ADDR_REG); -+ writel(FIELD_PREP(ASPEED_I2CD_DMA_LEN_MASK, -+ len), -+ bus->base + ASPEED_I2C_DMA_LEN_REG); -+ bus->dma_len = len; -+ } else if (bus->buf_base) { - command |= ASPEED_I2CD_RX_BUFF_ENABLE; - - if (msg->len - bus->buf_index > -@@ -1235,7 +1379,51 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) ++ writel(FIELD_PREP(ASPEED_I2CD_BUF_RX_SIZE_MASK, ++ len - 1) | ++ FIELD_PREP(ASPEED_I2CD_BUF_TX_COUNT_MASK, 0) | ++ FIELD_PREP(ASPEED_I2CD_BUF_OFFSET_MASK, ++ bus->buf_offset), ++ bus->base + ASPEED_I2C_BUF_CTRL_REG); ++ } + } else { + if (bus->buf_index + 1 == msg->len) + command |= ASPEED_I2CD_M_S_RX_CMD_LAST; +@@ -1260,7 +1368,51 @@ static void aspeed_i2c_set_xfer_mode(struct aspeed_i2c_bus *bus) sram_enabled = false; } - if (sram_enabled) { + /* -+ * Only AST2500 supports DMA mode under some limitations: ++ * Only AST2500 and AST2600 support DMA mode under some limitations: + * I2C is sharing the DMA H/W with UHCI host controller and MCTP + * controller. Since those controllers operate with DMA mode only, I2C + * has to use buffer mode or byte mode instead if one of those @@ -350,25 +399,25 @@ index 1b338492c68a..8dc6723bfaaf 100644 + * use DMA mode. + */ + if (sram_enabled && !IS_ENABLED(CONFIG_USB_UHCI_ASPEED) && -+ of_device_is_compatible(pdev->dev.of_node, -+ "aspeed,ast2500-i2c-bus")) { ++ !of_device_is_compatible(pdev->dev.of_node, ++ "aspeed,ast2400-i2c-bus")) { + u32 dma_len_max = ASPEED_I2CD_DMA_LEN_MASK >> + ASPEED_I2CD_DMA_LEN_SHIFT; + + ret = device_property_read_u32(&pdev->dev, + "aspeed,dma-buf-size", -+ &bus->dma_buf_size); -+ if (!ret && bus->dma_buf_size > dma_len_max) -+ bus->dma_buf_size = dma_len_max; ++ &bus->buf_size); ++ if (!ret && bus->buf_size > dma_len_max) ++ bus->buf_size = dma_len_max; + } + -+ if (bus->dma_buf_size) { ++ if (bus->buf_size) { + if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { + dev_warn(&pdev->dev, "No suitable DMA available\n"); + } else { + bus->dma_pool = dma_pool_create("i2c-aspeed", + &pdev->dev, -+ bus->dma_buf_size, ++ bus->buf_size, + ASPEED_I2CD_DMA_ALIGN, + 0); + if (bus->dma_pool) @@ -388,7 +437,7 @@ index 1b338492c68a..8dc6723bfaaf 100644 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -@@ -1275,24 +1463,33 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) +@@ -1365,24 +1517,33 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) */ ret = aspeed_i2c_init(bus, pdev); if (ret < 0) @@ -426,7 +475,7 @@ index 1b338492c68a..8dc6723bfaaf 100644 } static int aspeed_i2c_remove_bus(struct platform_device *pdev) -@@ -1310,6 +1507,10 @@ static int aspeed_i2c_remove_bus(struct platform_device *pdev) +@@ -1400,6 +1561,10 @@ static int aspeed_i2c_remove_bus(struct platform_device *pdev) reset_control_assert(bus->rst); diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0063-i2c-aspeed-add-general-call-support.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0063-i2c-aspeed-add-general-call-support.patch index 2f51c3fc9..899924f61 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0063-i2c-aspeed-add-general-call-support.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0063-i2c-aspeed-add-general-call-support.patch @@ -1,4 +1,4 @@ -From 3f73215941667176ba05f358f4ee08816299bd32 Mon Sep 17 00:00:00 2001 +From d731b53de05b8d69ea739f02275416126cf5fe4e Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo Date: Wed, 1 May 2019 13:27:34 -0700 Subject: [PATCH] i2c: aspeed: add general call support @@ -28,7 +28,7 @@ index d3f4a39f7ba6..c1ee99398517 100644 specified. - #retries : Number of retries for master transfer. diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index 8dc6723bfaaf..891b2b5c4b7a 100644 +index 3c9e491cbe4e..4420899e2c2d 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -59,6 +59,7 @@ @@ -65,7 +65,7 @@ index 8dc6723bfaaf..891b2b5c4b7a 100644 #endif /* CONFIG_I2C_SLAVE */ }; -@@ -315,6 +321,12 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) +@@ -423,6 +429,12 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) bus->slave_state = ASPEED_I2C_SLAVE_START; } @@ -78,7 +78,7 @@ index 8dc6723bfaaf..891b2b5c4b7a 100644 /* Slave is not currently active, irq was for someone else. */ if (bus->slave_state == ASPEED_I2C_SLAVE_INACTIVE) return irq_handled; -@@ -342,6 +354,21 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) +@@ -441,6 +453,21 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) else bus->slave_state = ASPEED_I2C_SLAVE_WRITE_REQUESTED; @@ -100,9 +100,9 @@ index 8dc6723bfaaf..891b2b5c4b7a 100644 } irq_handled |= ASPEED_I2CD_INTR_RX_DONE; } -@@ -462,11 +489,16 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - bus->base + ASPEED_I2C_CMD_REG); - } +@@ -487,11 +514,16 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value); + aspeed_i2c_slave_handle_write_received(bus, &value); break; + case ASPEED_I2C_SLAVE_GCALL_REQUESTED: + bus->slave_state = ASPEED_I2C_SLAVE_WRITE_RECEIVED; @@ -117,7 +117,7 @@ index 8dc6723bfaaf..891b2b5c4b7a 100644 /* Slave was just started. Waiting for the next event. */; break; default: -@@ -1084,6 +1116,8 @@ static void __aspeed_i2c_reg_slave(struct aspeed_i2c_bus *bus, u16 slave_addr) +@@ -1127,6 +1159,8 @@ static void __aspeed_i2c_reg_slave(struct aspeed_i2c_bus *bus, u16 slave_addr) /* Turn on slave mode. */ func_ctrl_reg_val = readl(bus->base + ASPEED_I2C_FUN_CTRL_REG); func_ctrl_reg_val |= ASPEED_I2CD_SLAVE_EN; @@ -126,7 +126,7 @@ index 8dc6723bfaaf..891b2b5c4b7a 100644 writel(func_ctrl_reg_val, bus->base + ASPEED_I2C_FUN_CTRL_REG); } -@@ -1122,6 +1156,8 @@ static int aspeed_i2c_unreg_slave(struct i2c_client *client) +@@ -1165,6 +1199,8 @@ static int aspeed_i2c_unreg_slave(struct i2c_client *client) /* Turn off slave mode. */ func_ctrl_reg_val = readl(bus->base + ASPEED_I2C_FUN_CTRL_REG); func_ctrl_reg_val &= ~ASPEED_I2CD_SLAVE_EN; @@ -135,7 +135,7 @@ index 8dc6723bfaaf..891b2b5c4b7a 100644 writel(func_ctrl_reg_val, bus->base + ASPEED_I2C_FUN_CTRL_REG); bus->slave = NULL; -@@ -1269,6 +1305,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus, +@@ -1312,6 +1348,9 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus, bus->base + ASPEED_I2C_FUN_CTRL_REG); #if IS_ENABLED(CONFIG_I2C_SLAVE) diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0068-i2c-aspeed-add-H-W-timeout-support.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0068-i2c-aspeed-add-H-W-timeout-support.patch index a5f4fa216..0e8a2b101 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0068-i2c-aspeed-add-H-W-timeout-support.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0068-i2c-aspeed-add-H-W-timeout-support.patch @@ -1,4 +1,4 @@ -From 3e359be7e8a96b068479d01aa671ff642d291bca Mon Sep 17 00:00:00 2001 +From b429cf11ecb2f6009dd9e062ea5e053718802d93 Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo Date: Thu, 11 Jul 2019 13:53:34 -0700 Subject: [PATCH] i2c: aspeed: add H/W timeout support @@ -11,7 +11,7 @@ Signed-off-by: Jae Hyun Yoo 1 file changed, 76 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index 891b2b5c4b7a..71ebf3bbf38b 100644 +index 4420899e2c2d..830b3d2cabad 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -55,6 +55,7 @@ @@ -79,10 +79,10 @@ index 891b2b5c4b7a..71ebf3bbf38b 100644 + return 0; +} + - static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - { - u32 command, irq_handled = 0; -@@ -313,6 +331,14 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + static inline void + aspeed_i2c_slave_handle_rx_done(struct aspeed_i2c_bus *bus, u32 irq_status, + u8 *value) +@@ -421,6 +439,14 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) if (!slave) return 0; @@ -97,7 +97,7 @@ index 891b2b5c4b7a..71ebf3bbf38b 100644 command = readl(bus->base + ASPEED_I2C_CMD_REG); /* Slave was requested, restart state machine. */ -@@ -655,7 +681,7 @@ static void aspeed_i2c_next_msg_or_stop(struct aspeed_i2c_bus *bus) +@@ -681,7 +707,7 @@ static void aspeed_i2c_next_msg_or_stop(struct aspeed_i2c_bus *bus) } } @@ -106,7 +106,7 @@ index 891b2b5c4b7a..71ebf3bbf38b 100644 { if (irq_status & ASPEED_I2CD_INTR_ARBIT_LOSS) return -EAGAIN; -@@ -686,9 +712,9 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) +@@ -840,9 +866,9 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) * should clear the command queue effectively taking us back to the * INACTIVE state. */ @@ -118,7 +118,7 @@ index 891b2b5c4b7a..71ebf3bbf38b 100644 irq_status); irq_handled |= (irq_status & ASPEED_I2CD_INTR_MASTER_ERRORS); if (bus->master_state != ASPEED_I2C_MASTER_INACTIVE) { -@@ -1264,6 +1290,7 @@ static u32 aspeed_i2c_25xx_get_clk_reg_val(struct device *dev, u32 divisor) +@@ -1307,6 +1333,7 @@ static u32 aspeed_i2c_25xx_get_clk_reg_val(struct device *dev, u32 divisor) /* precondition: bus.lock has been acquired. */ static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus) { @@ -126,7 +126,7 @@ index 891b2b5c4b7a..71ebf3bbf38b 100644 u32 divisor, clk_reg_val; divisor = DIV_ROUND_UP(bus->parent_clk_frequency, bus->bus_frequency); -@@ -1272,8 +1299,46 @@ static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus) +@@ -1315,8 +1342,46 @@ static int aspeed_i2c_init_clk(struct aspeed_i2c_bus *bus) ASPEED_I2CD_TIME_THDSTA_MASK | ASPEED_I2CD_TIME_TACST_MASK); clk_reg_val |= bus->get_clk_reg_val(bus->dev, divisor); @@ -174,7 +174,7 @@ index 891b2b5c4b7a..71ebf3bbf38b 100644 return 0; } -@@ -1288,6 +1353,11 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus, +@@ -1331,6 +1396,11 @@ static int aspeed_i2c_init(struct aspeed_i2c_bus *bus, /* Disable everything. */ writel(0, bus->base + ASPEED_I2C_FUN_CTRL_REG); diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0069-i2c-aspeed-add-SLAVE_ADDR_RECEIVED_PENDING-interrupt.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0069-i2c-aspeed-add-SLAVE_ADDR_RECEIVED_PENDING-interrupt.patch index a304de019..104279ace 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0069-i2c-aspeed-add-SLAVE_ADDR_RECEIVED_PENDING-interrupt.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0069-i2c-aspeed-add-SLAVE_ADDR_RECEIVED_PENDING-interrupt.patch @@ -1,4 +1,4 @@ -From 78ad5c6291df33b7cba0e6be9a2b6ed6e7bbd571 Mon Sep 17 00:00:00 2001 +From b43bdeb5f3aa297549655e67f0e6a5db5f592e34 Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo Date: Thu, 11 Jul 2019 14:04:39 -0700 Subject: [PATCH] i2c: aspeed: add SLAVE_ADDR_RECEIVED_PENDING interrupt @@ -15,7 +15,7 @@ Signed-off-by: Jae Hyun Yoo 1 file changed, 13 insertions(+) diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index 71ebf3bbf38b..a15f54f64b50 100644 +index 830b3d2cabad..a308d5896632 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -87,6 +87,7 @@ @@ -26,7 +26,7 @@ index 71ebf3bbf38b..a15f54f64b50 100644 #define ASPEED_I2CD_INTR_SLAVE_INACTIVE_TIMEOUT BIT(15) #define ASPEED_I2CD_INTR_SDA_DL_TIMEOUT BIT(14) #define ASPEED_I2CD_INTR_BUS_RECOVER_DONE BIT(13) -@@ -360,6 +361,18 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) +@@ -468,6 +469,18 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) dev_dbg(bus->dev, "slave irq status 0x%08x, cmd 0x%08x\n", irq_status, command); @@ -44,7 +44,7 @@ index 71ebf3bbf38b..a15f54f64b50 100644 + /* Slave was sent something. */ if (irq_status & ASPEED_I2CD_INTR_RX_DONE) { - if (bus->dma_buf && + aspeed_i2c_slave_handle_rx_done(bus, irq_status, &value); -- 2.7.4 diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0074-media-aspeed-refine-HSYNC-VSYNC-polarity-setting-log.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0074-media-aspeed-refine-HSYNC-VSYNC-polarity-setting-log.patch deleted file mode 100644 index 4118e366c..000000000 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0074-media-aspeed-refine-HSYNC-VSYNC-polarity-setting-log.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 1032b062669b7ee041d2f5a9f4729953655efe61 Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo -Date: Wed, 4 Sep 2019 14:52:40 -0700 -Subject: [PATCH] media: aspeed: refine HSYNC/VSYNC polarity setting logic - -Sometimes it detects weird resolutions such as 1024x287 when the -actual resolution is 1280x768. To resolve this issue, this commit -refines HSYNC/VSYNC polarity setting code for mode detection by -clearing the bits as normal polarity at the beginning of the first -mode detection like datasheet suggested, and refines polarity -setting logic so that the bits can be set or cleared properly. - -Signed-off-by: Jae Hyun Yoo ---- - drivers/media/platform/aspeed-video.c | 45 ++++++++++++++++++----------------- - 1 file changed, 23 insertions(+), 22 deletions(-) - -diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c -index 4ef37cfc8446..455c6af81236 100644 ---- a/drivers/media/platform/aspeed-video.c -+++ b/drivers/media/platform/aspeed-video.c -@@ -614,7 +614,7 @@ static void aspeed_video_check_and_set_polarity(struct aspeed_video *video) - int i; - int hsync_counter = 0; - int vsync_counter = 0; -- u32 sts; -+ u32 sts, ctrl; - - for (i = 0; i < NUM_POLARITY_CHECKS; ++i) { - sts = aspeed_video_read(video, VE_MODE_DETECT_STATUS); -@@ -629,30 +629,29 @@ static void aspeed_video_check_and_set_polarity(struct aspeed_video *video) - hsync_counter++; - } - -- if (hsync_counter < 0 || vsync_counter < 0) { -- u32 ctrl = 0; -+ ctrl = aspeed_video_read(video, VE_CTRL); - -- if (hsync_counter < 0) { -- ctrl = VE_CTRL_HSYNC_POL; -- video->detected_timings.polarities &= -- ~V4L2_DV_HSYNC_POS_POL; -- } else { -- video->detected_timings.polarities |= -- V4L2_DV_HSYNC_POS_POL; -- } -- -- if (vsync_counter < 0) { -- ctrl = VE_CTRL_VSYNC_POL; -- video->detected_timings.polarities &= -- ~V4L2_DV_VSYNC_POS_POL; -- } else { -- video->detected_timings.polarities |= -- V4L2_DV_VSYNC_POS_POL; -- } -+ if (hsync_counter < 0) { -+ ctrl |= VE_CTRL_HSYNC_POL; -+ video->detected_timings.polarities &= -+ ~V4L2_DV_HSYNC_POS_POL; -+ } else { -+ ctrl &= ~VE_CTRL_HSYNC_POL; -+ video->detected_timings.polarities |= -+ V4L2_DV_HSYNC_POS_POL; -+ } - -- if (ctrl) -- aspeed_video_update(video, VE_CTRL, 0, ctrl); -+ if (vsync_counter < 0) { -+ ctrl |= VE_CTRL_VSYNC_POL; -+ video->detected_timings.polarities &= -+ ~V4L2_DV_VSYNC_POS_POL; -+ } else { -+ ctrl &= ~VE_CTRL_VSYNC_POL; -+ video->detected_timings.polarities |= -+ V4L2_DV_VSYNC_POS_POL; - } -+ -+ aspeed_video_write(video, VE_CTRL, ctrl); - } - - static bool aspeed_video_alloc_buf(struct aspeed_video *video, -@@ -741,6 +740,8 @@ static void aspeed_video_get_resolution(struct aspeed_video *video) - } - - set_bit(VIDEO_RES_DETECT, &video->flags); -+ aspeed_video_update(video, VE_CTRL, -+ VE_CTRL_VSYNC_POL | VE_CTRL_HSYNC_POL, 0); - aspeed_video_enable_mode_detect(video); - - rc = wait_event_interruptible_timeout(video->wait, --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0075-Refine-initialization-flow-in-I2C-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0075-Refine-initialization-flow-in-I2C-driver.patch index 009fccacf..52c3617d6 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0075-Refine-initialization-flow-in-I2C-driver.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0075-Refine-initialization-flow-in-I2C-driver.patch @@ -1,4 +1,4 @@ -From 83c1fcb7dacb59d22b41356e3b7009ff2387d448 Mon Sep 17 00:00:00 2001 +From 93ba2aeb9ad3899e2b72877daa47376a6bf192b6 Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo Date: Mon, 23 Sep 2019 13:48:49 -0700 Subject: [PATCH] Refine initialization flow in I2C driver @@ -15,12 +15,12 @@ Signed-off-by: Jae Hyun Yoo 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index a15f54f64b50..62b803e15ce2 100644 +index a308d5896632..b32611088c82 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c -@@ -1454,6 +1454,11 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) - if (IS_ERR(bus->base)) - return PTR_ERR(bus->base); +@@ -1588,6 +1588,11 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) + + bus->dev = &pdev->dev; + /* Disable bus and clean up any left over interrupt state. */ + writel(0, bus->base + ASPEED_I2C_FUN_CTRL_REG); @@ -30,9 +30,9 @@ index a15f54f64b50..62b803e15ce2 100644 parent_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(parent_clk)) return PTR_ERR(parent_clk); -@@ -1576,17 +1581,6 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) - - bus->dev = &pdev->dev; +@@ -1630,17 +1635,6 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) + strlcpy(bus->adap.name, pdev->name, sizeof(bus->adap.name)); + i2c_set_adapdata(&bus->adap, bus); - /* Clean up any left over interrupt state. */ - writel(0, bus->base + ASPEED_I2C_INTR_CTRL_REG); @@ -48,7 +48,7 @@ index a15f54f64b50..62b803e15ce2 100644 irq = irq_of_parse_and_map(pdev->dev.of_node, 0); ret = devm_request_irq(&pdev->dev, irq, aspeed_i2c_bus_irq, 0, dev_name(&pdev->dev), bus); -@@ -1599,6 +1593,10 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) +@@ -1653,6 +1647,10 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev) platform_set_drvdata(pdev, bus); diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0076-media-aspeed-clear-garbage-interrupts.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0076-media-aspeed-clear-garbage-interrupts.patch deleted file mode 100644 index 0cf9913fe..000000000 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0076-media-aspeed-clear-garbage-interrupts.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 5f89fa4b6468771b5de6e73454bf0ea546249b7b Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo -Date: Thu, 26 Sep 2019 12:15:23 -0700 -Subject: [PATCH] media: aspeed: clear garbage interrupts - -CAPTURE_COMPLETE and FRAME_COMPLETE interrupts come even when these -are disabled in the VE_INTERRUPT_CTRL register and eventually this -behavior causes disabling irq itself like below: - -[10055.108784] irq 23: nobody cared (try booting with the "irqpoll" option) -[10055.115525] CPU: 0 PID: 331 Comm: swampd Tainted: G W 5.3.0-4fde000-dirty-d683e2e #1 -[10055.124565] Hardware name: Generic DT based system -[10055.129355] Backtrace: -[10055.131854] [<80107d7c>] (dump_backtrace) from [<80107fb0>] (show_stack+0x20/0x24) -[10055.139431] r7:00000017 r6:00000001 r5:00000000 r4:9d51dc00 -[10055.145120] [<80107f90>] (show_stack) from [<8074bf50>] (dump_stack+0x20/0x28) -[10055.152361] [<8074bf30>] (dump_stack) from [<80150ffc>] (__report_bad_irq+0x40/0xc0) -[10055.160109] [<80150fbc>] (__report_bad_irq) from [<80150f2c>] (note_interrupt+0x23c/0x294) -[10055.168374] r9:015b6e60 r8:00000000 r7:00000017 r6:00000001 r5:00000000 r4:9d51dc00 -[10055.176136] [<80150cf0>] (note_interrupt) from [<8014df1c>] (handle_irq_event_percpu+0x88/0x98) -[10055.184835] r10:7eff7910 r9:015b6e60 r8:00000000 r7:9d417600 r6:00000001 r5:00000002 -[10055.192657] r4:9d51dc00 r3:00000000 -[10055.196248] [<8014de94>] (handle_irq_event_percpu) from [<8014df64>] (handle_irq_event+0x38/0x4c) -[10055.205113] r5:80b56d50 r4:9d51dc00 -[10055.208697] [<8014df2c>] (handle_irq_event) from [<80151f1c>] (handle_level_irq+0xbc/0x12c) -[10055.217037] r5:80b56d50 r4:9d51dc00 -[10055.220623] [<80151e60>] (handle_level_irq) from [<8014d4b8>] (generic_handle_irq+0x30/0x44) -[10055.229052] r5:80b56d50 r4:00000017 -[10055.232648] [<8014d488>] (generic_handle_irq) from [<8014d524>] (__handle_domain_irq+0x58/0xb4) -[10055.241356] [<8014d4cc>] (__handle_domain_irq) from [<801021e4>] (avic_handle_irq+0x68/0x70) -[10055.249797] r9:015b6e60 r8:00c5387d r7:00c5387d r6:ffffffff r5:9dd33fb0 r4:9d402380 -[10055.257539] [<8010217c>] (avic_handle_irq) from [<80101e34>] (__irq_usr+0x54/0x80) -[10055.265105] Exception stack(0x9dd33fb0 to 0x9dd33ff8) -[10055.270152] 3fa0: 015d0530 00000000 00000000 015d0538 -[10055.278328] 3fc0: 015d0530 015b6e60 00000000 00000000 0052c5d0 015b6e60 7eff7910 7eff7918 -[10055.286496] 3fe0: 76ce5614 7eff7908 0050e2f4 76a3a08c 20000010 ffffffff -[10055.293104] r5:20000010 r4:76a3a08c -[10055.296673] handlers: -[10055.298967] [<79f218a5>] irq_default_primary_handler threaded [<1de88514>] aspeed_video_irq -[10055.307344] Disabling IRQ #23 - -To fix this issue, this commit makes the interrupt handler clear -these garbage interrupts. This driver enables and uses only -COMP_COMPLETE interrupt. - -Signed-off-by: Jae Hyun Yoo ---- - drivers/media/platform/aspeed-video.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c -index 455c6af81236..0473f3141329 100644 ---- a/drivers/media/platform/aspeed-video.c -+++ b/drivers/media/platform/aspeed-video.c -@@ -606,6 +606,16 @@ static irqreturn_t aspeed_video_irq(int irq, void *arg) - aspeed_video_start_frame(video); - } - -+ /* -+ * CAPTURE_COMPLETE and FRAME_COMPLETE interrupts come even when these -+ * are disabled in the VE_INTERRUPT_CTRL register so clear them to -+ * prevent unnecessary interrupt calls. -+ */ -+ if (sts & VE_INTERRUPT_CAPTURE_COMPLETE) -+ sts &= ~VE_INTERRUPT_CAPTURE_COMPLETE; -+ if (sts & VE_INTERRUPT_FRAME_COMPLETE) -+ sts &= ~VE_INTERRUPT_FRAME_COMPLETE; -+ - return sts ? IRQ_NONE : IRQ_HANDLED; - } - --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0082-ARM-dts-aspeed-g6-add-USB-virtual-hub-fixup.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0082-ARM-dts-aspeed-g6-add-USB-virtual-hub-fixup.patch deleted file mode 100644 index f950c9262..000000000 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0082-ARM-dts-aspeed-g6-add-USB-virtual-hub-fixup.patch +++ /dev/null @@ -1,53 +0,0 @@ -From e0e33dfafe30f6dfb175caaf6be99aa9cbfe295a Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo -Date: Wed, 20 Nov 2019 13:06:58 -0800 -Subject: [PATCH] ARM: dts: aspeed-g6: add USB virtual hub fixup - -This commit adds dt and pinctrl fixup for USB virtual hub. - -Signed-off-by: Jae Hyun Yoo ---- - arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi | 5 +++++ - arch/arm/boot/dts/aspeed-g6.dtsi | 10 ++++++++++ - 2 files changed, 15 insertions(+) - -diff --git a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi -index 045ce66ca876..6ea66aaf9dd0 100644 ---- a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi -+++ b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi -@@ -1112,6 +1112,11 @@ - groups = "UART9"; - }; - -+ pinctrl_usb2adp_default: usb2adp_default { -+ function = "USB2ADP"; -+ groups = "USBA"; -+ }; -+ - pinctrl_vb_default: vb_default { - function = "VB"; - groups = "VB"; -diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi -index 33fcd89db6b8..b880e8e8f999 100644 ---- a/arch/arm/boot/dts/aspeed-g6.dtsi -+++ b/arch/arm/boot/dts/aspeed-g6.dtsi -@@ -272,6 +272,16 @@ - status = "disabled"; - }; - -+ vhub: usb-vhub@1e6a0000 { -+ compatible = "aspeed,ast2600-usb-vhub"; -+ reg = <0x1e6a0000 0x300>; -+ interrupts = ; -+ clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usb2adp_default>; -+ status = "disabled"; -+ }; -+ - apb { - compatible = "simple-bus"; - #address-cells = <1>; --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0083-usb-gadget-aspeed-add-ast2600-compatible-string.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0083-usb-gadget-aspeed-add-ast2600-compatible-string.patch deleted file mode 100644 index 3f6f3ce91..000000000 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0083-usb-gadget-aspeed-add-ast2600-compatible-string.patch +++ /dev/null @@ -1,32 +0,0 @@ -From eedb53957b507bda2b9f6025149d2052e0598f76 Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo -Date: Wed, 20 Nov 2019 12:49:46 -0800 -Subject: [PATCH] usb: gadget: aspeed: add ast2600 compatible string - -This commit adds "aspeed,ast2600-usb-vhub" compatible string to -use it for AST2600 USB virtual hub driver. AST2600 support total 7 -downstream device ports so this driver should be modified later to -support the additional ports. - -Signed-off-by: Jae Hyun Yoo ---- - drivers/usb/gadget/udc/aspeed-vhub/core.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c b/drivers/usb/gadget/udc/aspeed-vhub/core.c -index 90b134d..905e1cf 100644 ---- a/drivers/usb/gadget/udc/aspeed-vhub/core.c -+++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c -@@ -407,6 +407,9 @@ static const struct of_device_id ast_vhub_dt_ids[] = { - { - .compatible = "aspeed,ast2500-usb-vhub", - }, -+ { -+ .compatible = "aspeed,ast2600-usb-vhub", -+ }, - { } - }; - MODULE_DEVICE_TABLE(of, ast_vhub_dt_ids); --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0090-peci-cpupower-driver-1.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0090-peci-cpupower-driver-1.patch new file mode 100644 index 000000000..475e9611f --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0090-peci-cpupower-driver-1.patch @@ -0,0 +1,405 @@ +From e40f7d10d5306c075e2fc7e538ce1efc70eeb448 Mon Sep 17 00:00:00 2001 +From: ZhikuiRen +Date: Thu, 9 Jan 2020 10:48:00 -0800 +Subject: [PATCH] Add peci-cpupower driver + +peci-cpupower reads CPU energy counter through peci +and computes average power in mW since last read. + +Signed-off-by: ZhikuiRen +--- + Documentation/hwmon/index.rst | 1 + + Documentation/hwmon/peci-cpupower.rst | 52 ++++++++ + arch/arm/configs/aspeed_g5_defconfig | 1 + + drivers/hwmon/Kconfig | 14 +++ + drivers/hwmon/Makefile | 1 + + drivers/hwmon/peci-cpupower.c | 231 ++++++++++++++++++++++++++++++++++ + drivers/mfd/intel-peci-client.c | 1 + + include/uapi/linux/peci-ioctl.h | 1 + + 8 files changed, 302 insertions(+) + create mode 100644 Documentation/hwmon/peci-cpupower.rst + create mode 100644 drivers/hwmon/peci-cpupower.c + +diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst +index 7d894c9..0bde0ef 100644 +--- a/Documentation/hwmon/index.rst ++++ b/Documentation/hwmon/index.rst +@@ -130,6 +130,7 @@ Hardware Monitoring Kernel Drivers + pcf8591 + peci-cputemp + peci-dimmtemp ++ peci-cpupower + pmbus + powr1220 + pxe1610 +diff --git a/Documentation/hwmon/peci-cpupower.rst b/Documentation/hwmon/peci-cpupower.rst +new file mode 100644 +index 0000000..4d7bd61 +--- /dev/null ++++ b/Documentation/hwmon/peci-cpupower.rst +@@ -0,0 +1,52 @@ ++.. SPDX-License-Identifier: GPL-2.0 ++ ++Kernel driver peci-cpupower ++========================== ++ ++:Copyright: |copy| 2018-2020 Intel Corporation ++ ++Supported chips: ++ One of Intel server CPUs listed below which is connected to a PECI bus. ++ * Intel Xeon E5/E7 v3 server processors ++ Intel Xeon E5-14xx v3 family ++ Intel Xeon E5-24xx v3 family ++ Intel Xeon E5-16xx v3 family ++ Intel Xeon E5-26xx v3 family ++ Intel Xeon E5-46xx v3 family ++ Intel Xeon E7-48xx v3 family ++ Intel Xeon E7-88xx v3 family ++ * Intel Xeon E5/E7 v4 server processors ++ Intel Xeon E5-16xx v4 family ++ Intel Xeon E5-26xx v4 family ++ Intel Xeon E5-46xx v4 family ++ Intel Xeon E7-48xx v4 family ++ Intel Xeon E7-88xx v4 family ++ * Intel Xeon Scalable server processors ++ Intel Xeon D family ++ Intel Xeon Bronze family ++ Intel Xeon Silver family ++ Intel Xeon Gold family ++ Intel Xeon Platinum family ++ ++ Addresses scanned: PECI client address 0x30 - 0x37 ++ Datasheet: Available from http://www.intel.com/design/literature.htm ++ ++Author: ++ Zhikui Ren ++ ++Description ++----------- ++ ++This driver implements a generic PECI hwmon feature which provides ++average power consumption readings of the CPU package based on energy counter ++accessible using the PECI Client Command Suite via the processor PECI client. ++ ++Power values are average power since last measure given in milli Watt and ++will be measurable only when the target CPU is powered on. ++ ++``sysfs`` interface ++------------------- ++======================= ======================================================= ++power1_average Provides average power since last read in milli Watt. ++power1_label Provides string "Average Power". ++======================= ======================================================= +diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig +index 1e589a0..0e50040 100644 +--- a/arch/arm/configs/aspeed_g5_defconfig ++++ b/arch/arm/configs/aspeed_g5_defconfig +@@ -177,6 +177,7 @@ CONFIG_SENSORS_OCC_P8_I2C=y + CONFIG_SENSORS_OCC_P9_SBE=y + CONFIG_SENSORS_PECI_CPUTEMP=y + CONFIG_SENSORS_PECI_DIMMTEMP=y ++CONFIG_SENSORS_PECI_CPUPOWER=y + CONFIG_PMBUS=y + CONFIG_SENSORS_ADM1275=y + CONFIG_SENSORS_IBM_CFFPS=y +diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +index 8312b37..07d8826 100644 +--- a/drivers/hwmon/Kconfig ++++ b/drivers/hwmon/Kconfig +@@ -1361,6 +1361,20 @@ config SENSORS_PECI_DIMMTEMP + This driver can also be built as a module. If so, the module + will be called peci-dimmtemp. + ++config SENSORS_PECI_CPUPOWER ++ tristate "PECI CPU power monitoring support" ++ depends on PECI ++ select MFD_INTEL_PECI_CLIENT ++ help ++ If you say yes here you get support for the generic Intel PECI ++ cputemp driver which provides average engergy ++ readings of the CPU package using ++ the PECI Client Command Suite via the processor PECI client. ++ Check Documentation/hwmon/peci-cpupower for details. ++ ++ This driver can also be built as a module. If so, the module ++ will be called peci-cpupower. ++ + source "drivers/hwmon/pmbus/Kconfig" + + config SENSORS_PWM_FAN +diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile +index e74ea92..fab43fd 100644 +--- a/drivers/hwmon/Makefile ++++ b/drivers/hwmon/Makefile +@@ -144,6 +144,7 @@ obj-$(CONFIG_SENSORS_PC87427) += pc87427.o + obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o + obj-$(CONFIG_SENSORS_PECI_CPUTEMP) += peci-cputemp.o + obj-$(CONFIG_SENSORS_PECI_DIMMTEMP) += peci-dimmtemp.o ++obj-$(CONFIG_SENSORS_PECI_CPUPOWER) += peci-cpupower.o + obj-$(CONFIG_SENSORS_POWR1220) += powr1220.o + obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o + obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o +diff --git a/drivers/hwmon/peci-cpupower.c b/drivers/hwmon/peci-cpupower.c +new file mode 100644 +index 0000000..6907696 +--- /dev/null ++++ b/drivers/hwmon/peci-cpupower.c +@@ -0,0 +1,231 @@ ++// SPDX-License-Identifier: GPL-2.0 ++// Copyright (c) 2018-2020 Intel Corporation ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "peci-hwmon.h" ++ ++#define POWER_DEFAULT_CHANNEL_NUMS 1 ++ ++struct peci_cpupower { ++ struct peci_client_manager *mgr; ++ struct device *dev; ++ char name[PECI_NAME_SIZE]; ++ const struct cpu_gen_info *gen_info; ++ struct peci_sensor_data energy; ++ long avg_power_val; ++ u64 core_mask; ++ u32 power_config[POWER_DEFAULT_CHANNEL_NUMS + 1]; ++ uint config_idx; ++ struct hwmon_channel_info power_info; ++ const struct hwmon_channel_info *info[2]; ++ struct hwmon_chip_info chip; ++}; ++ ++enum cpupower_channels { ++ average_power, ++}; ++ ++static const u32 config_table[POWER_DEFAULT_CHANNEL_NUMS] = { ++ /* average power */ ++ HWMON_P_LABEL | HWMON_P_AVERAGE, ++}; ++ ++static const char *cpupower_label[POWER_DEFAULT_CHANNEL_NUMS] = { ++ "Average Power", ++}; ++ ++static int get_average_power(struct peci_cpupower *priv) ++{ ++ u8 pkg_cfg[4]; ++ int ret; ++ ++ if (!peci_sensor_need_update(&priv->energy)) ++ return 0; ++ ++ ret = peci_client_read_package_config(priv->mgr, ++ PECI_MBX_INDEX_TDP_UNITS, ++ PECI_PKG_ID_PKG_ENERGY_STATUS, ++ pkg_cfg); ++ ++ u32 power_unit = ((le32_to_cpup((__le32 *)pkg_cfg)) & 0x1f00) >> 8; ++ ++ dev_dbg(priv->dev, "cpupower units %d (1J/pow(2, unit))\n", ++ power_unit); ++ ++ ret = peci_client_read_package_config(priv->mgr, ++ PECI_MBX_INDEX_ENERGY_COUNTER, ++ PECI_PKG_ID_PKG_ENERGY_STATUS, ++ pkg_cfg); ++ if (!ret) { ++ u32 energy_cnt = le32_to_cpup((__le32 *)pkg_cfg); ++ ulong jif = jiffies; ++ ulong elapsed = (jif - priv->energy.last_updated); ++ long power_val = 0; ++ /* ++ * Don't calculate average power for first counter read or ++ * counter wrapped around or last counter read was more than ++ * 60 minutes ago (jiffies did not wrap and power calculation ++ * does not overflow or underflow ++ */ ++ if (priv->energy.last_updated > 0 && ++ energy_cnt > priv->energy.value && ++ (elapsed < (HZ * 3600))) { ++ power_val = (long)(energy_cnt - priv->energy.value) ++ / elapsed * HZ; ++ dev_dbg(priv->dev, "countDiff %d, jiffes elapsed %d, raw powerValue %d scale to %d mW\n", ++ (long)(energy_cnt - priv->energy.value), ++ elapsed, power_val, ++ power_val >> (power_unit - 10)); ++ } else { ++ dev_dbg(priv->dev, "countDiff %d, jiffes elapsed %d, skipping calculate power, try agin\n", ++ (long)(energy_cnt - priv->energy.value), ++ elapsed); ++ ret = -EAGAIN; ++ } ++ ++ priv->energy.value = energy_cnt; ++ priv->avg_power_val = power_val >> ((power_unit - 10)); ++ peci_sensor_mark_updated(&priv->energy); ++ ++ dev_dbg(priv->dev, "energy counter 0x%8x, average power %dmW, jif %u, HZ is %d jiffies\n", ++ priv->energy.value, priv->avg_power_val, ++ jif, HZ); ++ } ++ return ret; ++} ++ ++static int cpupower_read_string(struct device *dev, ++ enum hwmon_sensor_types type, ++ u32 attr, int channel, const char **str) ++{ ++ if (attr != hwmon_power_label) ++ return -EOPNOTSUPP; ++ if (channel >= POWER_DEFAULT_CHANNEL_NUMS) ++ return -EOPNOTSUPP; ++ *str = cpupower_label[channel]; ++ ++ return 0; ++} ++ ++static int cpupower_read(struct device *dev, ++ enum hwmon_sensor_types type, ++ u32 attr, int channel, long *val) ++{ ++ struct peci_cpupower *priv = dev_get_drvdata(dev); ++ int ret; ++ ++ if (channel >= POWER_DEFAULT_CHANNEL_NUMS || ++ !(priv->power_config[channel] & BIT(attr))) ++ return -EOPNOTSUPP; ++ ++ switch (attr) { ++ case hwmon_power_average: ++ switch (channel) { ++ case average_power: ++ ret = get_average_power(priv); ++ if (ret) ++ break; ++ ++ *val = priv->avg_power_val; ++ break; ++ default: ++ break; ++ } ++ break; ++ default: ++ ret = -EOPNOTSUPP; ++ break; ++ } ++ ++ return ret; ++} ++ ++static umode_t cpupower_is_visible(const void *data, ++ enum hwmon_sensor_types type, ++ u32 attr, int channel) ++{ ++ const struct peci_cpupower *priv = data; ++ ++ if (channel < POWER_DEFAULT_CHANNEL_NUMS || ++ (priv->power_config[channel] & BIT(attr))) ++ return 0444; ++ ++ return 0; ++} ++ ++static const struct hwmon_ops cpupower_ops = { ++ .is_visible = cpupower_is_visible, ++ .read_string = cpupower_read_string, ++ .read = cpupower_read, ++}; ++ ++static int peci_cpupower_probe(struct platform_device *pdev) ++{ ++ struct peci_client_manager *mgr = dev_get_drvdata(pdev->dev.parent); ++ struct device *dev = &pdev->dev; ++ struct peci_cpupower *priv; ++ struct device *hwmon_dev; ++ ++ if ((mgr->client->adapter->cmd_mask & ++ (BIT(PECI_CMD_RD_PKG_CFG))) != ++ (BIT(PECI_CMD_RD_PKG_CFG))) { ++ return -ENODEV; ++ } ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ dev_set_drvdata(dev, priv); ++ priv->mgr = mgr; ++ priv->dev = dev; ++ priv->gen_info = mgr->gen_info; ++ ++ snprintf(priv->name, PECI_NAME_SIZE, "peci_cpupower.cpu%d", ++ mgr->client->addr - PECI_BASE_ADDR); ++ ++ priv->power_config[priv->config_idx++] = config_table[average_power]; ++ ++ priv->chip.ops = &cpupower_ops; ++ priv->chip.info = priv->info; ++ ++ priv->info[0] = &priv->power_info; ++ ++ priv->power_info.type = hwmon_power; ++ priv->power_info.config = priv->power_config; ++ ++ hwmon_dev = devm_hwmon_device_register_with_info(priv->dev, ++ priv->name, ++ priv, ++ &priv->chip, ++ NULL); ++ ++ if (IS_ERR(hwmon_dev)) ++ return PTR_ERR(hwmon_dev); ++ ++ dev_dbg(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), priv->name); ++ ++ return 0; ++} ++ ++static const struct platform_device_id peci_cpupower_ids[] = { ++ { .name = "peci-cpupower", .driver_data = 0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(platform, peci_cpupower_ids); ++ ++static struct platform_driver peci_cpupower_driver = { ++ .probe = peci_cpupower_probe, ++ .id_table = peci_cpupower_ids, ++ .driver = { .name = KBUILD_MODNAME, }, ++}; ++module_platform_driver(peci_cpupower_driver); ++ ++MODULE_AUTHOR("Zhikui Ren "); ++MODULE_DESCRIPTION("PECI cpupower driver"); ++MODULE_LICENSE("GPL v2"); +diff --git a/drivers/mfd/intel-peci-client.c b/drivers/mfd/intel-peci-client.c +index 9751b04..0c62ad6 100644 +--- a/drivers/mfd/intel-peci-client.c ++++ b/drivers/mfd/intel-peci-client.c +@@ -21,6 +21,7 @@ + static struct mfd_cell peci_functions[] = { + { .name = "peci-cputemp", }, + { .name = "peci-dimmtemp", }, ++ { .name = "peci-cpupower", }, + }; + + static const struct cpu_gen_info cpu_gen_info_table[] = { +diff --git a/include/uapi/linux/peci-ioctl.h b/include/uapi/linux/peci-ioctl.h +index 843930f..d16f7c9 100644 +--- a/include/uapi/linux/peci-ioctl.h ++++ b/include/uapi/linux/peci-ioctl.h +@@ -231,6 +231,7 @@ struct peci_rd_pkg_cfg_msg { + #define PECI_PKG_ID_MAX_THREAD_ID 0x0003 /* Max Thread ID */ + #define PECI_PKG_ID_MICROCODE_REV 0x0004 /* CPU Microcode Update Revision */ + #define PECI_PKG_ID_MACHINE_CHECK_STATUS 0x0005 /* Machine Check Status */ ++#define PECI_PKG_ID_PKG_ENERGY_STATUS 0x00ff /* Average Energy */ + + __u8 rx_len; + __u8 cc; +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0092-SPI-Quad-IO-driver-support-AST2600.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0092-SPI-Quad-IO-driver-support-AST2600.patch new file mode 100644 index 000000000..dd756edbe --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0092-SPI-Quad-IO-driver-support-AST2600.patch @@ -0,0 +1,136 @@ +From 879834a305bd5c0cbf3c60f8fe235cea8783fe35 Mon Sep 17 00:00:00 2001 +From: arun-pm +Date: Tue, 3 Dec 2019 17:22:28 +0530 +Subject: [PATCH] SPI Quad IO driver support AST2600 + +This commit adds spi driver quad io support for AST2600 + +Note:- Removed n25q00 Quad I/O support for the time being due to clock issue + with chip 'Micron 8UA15 - rw182 (128MB)' while enabling Quad I/O mode. + +Signed-off-by: arun-pm +--- + drivers/mtd/spi-nor/aspeed-smc.c | 49 ++++++++++++++++++++++++++++++++++------ + drivers/mtd/spi-nor/spi-nor.c | 7 +++++- + 2 files changed, 48 insertions(+), 8 deletions(-) + +diff --git a/drivers/mtd/spi-nor/aspeed-smc.c b/drivers/mtd/spi-nor/aspeed-smc.c +index 0805dcab8cb1..305c1940e822 100644 +--- a/drivers/mtd/spi-nor/aspeed-smc.c ++++ b/drivers/mtd/spi-nor/aspeed-smc.c +@@ -21,6 +21,11 @@ + #include + + #define DEVICE_NAME "aspeed-smc" ++#define AST2600A0 0x05000303 ++#define AST2600A0_MAX_FREQ 50000000 ++#define AST2600A0_SAFE_FREQ 40000000 ++#define AST_MAX_FREQ 100000000 ++#define AST2600_REVISION_ID_SCU 0x1e6e2004 + + /* + * The driver only support SPI flash +@@ -542,6 +547,10 @@ static int aspeed_smc_get_io_mode(struct aspeed_smc_chip *chip) + return CONTROL_IO_DUAL_DATA; + case SNOR_PROTO_1_2_2: + return CONTROL_IO_DUAL_ADDR_DATA; ++ case SNOR_PROTO_1_1_4: ++ return CONTROL_IO_QUAD_DATA; ++ case SNOR_PROTO_1_4_4: ++ return CONTROL_IO_QUAD_ADDR_DATA; + default: + dev_err(chip->nor.dev, "unsupported SPI read mode\n"); + return -EINVAL; +@@ -573,7 +582,7 @@ static ssize_t aspeed_smc_read_user(struct spi_nor *nor, loff_t from, + aspeed_smc_write_to_ahb(chip->ahb_base, &dummy, sizeof(dummy)); + + /* Set IO mode only for data */ +- if (io_mode == CONTROL_IO_DUAL_DATA) ++ if (io_mode == CONTROL_IO_DUAL_DATA || io_mode == CONTROL_IO_QUAD_DATA) + aspeed_smc_set_io_mode(chip, io_mode); + + aspeed_smc_read_from_ahb(read_buf, chip->ahb_base, len); +@@ -1222,20 +1231,35 @@ static int aspeed_smc_chip_setup_finish(struct aspeed_smc_chip *chip) + return 0; + } + ++static void aspeed_allowed_max_freq(struct aspeed_smc_chip *chip) ++{ ++ void __iomem *scu_ast_revision_id = ioremap(AST2600_REVISION_ID_SCU, 4); ++ u32 rev_id = readl(scu_ast_revision_id); ++ ++ /*Limit max spi frequency less than 50MHz on AST2600-A0 due ++ * to FWSPICLK signal quality issue. ++ */ ++ if(rev_id == AST2600A0 && chip->clk_rate >= AST2600A0_MAX_FREQ) ++ chip->clk_rate = AST2600A0_SAFE_FREQ; ++} ++ ++static u32 get_hwcaps(unsigned int tx_width){ ++ if(tx_width == 4) ++ return SNOR_HWCAPS_READ_1_1_4; ++ else ++ return SNOR_HWCAPS_READ_1_1_2; ++} ++ + static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller, + struct device_node *np, struct resource *r) + { +- const struct spi_nor_hwcaps hwcaps = { +- .mask = SNOR_HWCAPS_READ | +- SNOR_HWCAPS_READ_FAST | +- SNOR_HWCAPS_READ_1_1_2 | +- SNOR_HWCAPS_PP, +- }; ++ struct spi_nor_hwcaps hwcaps; + const struct aspeed_smc_info *info = controller->info; + struct device *dev = controller->dev; + struct device_node *child; + unsigned int cs; + int ret = -ENODEV; ++ unsigned int spi_tx_width; + + for_each_available_child_of_node(np, child) { + struct aspeed_smc_chip *chip; +@@ -1276,9 +1300,20 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller, + &chip->clk_rate)) { + chip->clk_rate = ASPEED_SPI_DEFAULT_FREQ; + } ++ aspeed_allowed_max_freq(chip); + dev_info(dev, "Using %d MHz SPI frequency\n", + chip->clk_rate / 1000000); + ++ if (of_property_read_u32(child, "spi-tx-bus-width", ++ &spi_tx_width)) { ++ spi_tx_width = 2; ++ } ++ dev_info(dev, "tx width: %ld\n", spi_tx_width); ++ ++ hwcaps.mask = SNOR_HWCAPS_READ | ++ SNOR_HWCAPS_READ_FAST | ++ get_hwcaps(spi_tx_width) | ++ SNOR_HWCAPS_PP; + chip->controller = controller; + chip->ctl = controller->regs + info->ctl0 + cs * 4; + chip->cs = cs; +diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c +index 19fe44b0965a..c69ef8b56700 100644 +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -2310,7 +2310,12 @@ static const struct flash_info spi_nor_ids[] = { + { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, +- { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, ++ /* Removed n25q00 Quad I/O support for the time being due to clock issue with chip 'Micron 8UA15 - rw182 (128MB)' ++ * while enabling Quad I/O mode. As this chip is default shipped in platforms, marking it ++ * as Not supported for the time being. Once all chips are replaced with the new model, this can be enabled ++ * back(Note:- Certain other chips having same name(n25q00) but different part number has no issues). ++ */ ++ { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | NO_CHIP_ERASE) }, + { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, + { "mt25ql02g", INFO(0x20ba22, 0, 64 * 1024, 4096, + SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0093-ipmi-ipmb_dev_int-add-quick-fix-for-raw-I2C-type-reg.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0093-ipmi-ipmb_dev_int-add-quick-fix-for-raw-I2C-type-reg.patch new file mode 100644 index 000000000..4b3b6b838 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0093-ipmi-ipmb_dev_int-add-quick-fix-for-raw-I2C-type-reg.patch @@ -0,0 +1,37 @@ +From 8be7c34e78bd09fa95ce9972332c8c2bb950ec03 Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo +Date: Tue, 28 Jan 2020 16:14:07 -0800 +Subject: [PATCH] ipmi: ipmb_dev_int: add quick fix for raw I2C type + registration + +This commit adds quick fix for cases of run time registration +through sysfs. It should be fixed later by adding parsing code for +ipmb_id instead. + +This is a temporary fix. Do not upstream it. + +Signed-off-by: Jae Hyun Yoo +--- + drivers/char/ipmi/ipmb_dev_int.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/char/ipmi/ipmb_dev_int.c b/drivers/char/ipmi/ipmb_dev_int.c +index 382e4a1df510..c5db37266724 100644 +--- a/drivers/char/ipmi/ipmb_dev_int.c ++++ b/drivers/char/ipmi/ipmb_dev_int.c +@@ -328,8 +328,12 @@ static int ipmb_probe(struct i2c_client *client, + if (ret) + return ret; + ++#if 1 /* FIXME: Quick fix. Need to add parsing code for ipmb_id instead */ ++ ipmb_dev->is_i2c_protocol = true; ++#else + ipmb_dev->is_i2c_protocol + = device_property_read_bool(&client->dev, "i2c-protocol"); ++#endif + + ipmb_dev->client = client; + i2c_set_clientdata(client, ipmb_dev); +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0094-Return-link-speed-and-duplex-settings-for-the-NCSI-c.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0094-Return-link-speed-and-duplex-settings-for-the-NCSI-c.patch new file mode 100644 index 000000000..3e426edcd --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0094-Return-link-speed-and-duplex-settings-for-the-NCSI-c.patch @@ -0,0 +1,57 @@ +From f280c15c79e7d13e4a59d413a3091eb21b56dd92 Mon Sep 17 00:00:00 2001 +From: Johnathan Mantey +Date: Mon, 27 Jan 2020 09:03:56 -0800 +Subject: [PATCH] Return link speed and duplex settings for the NCSI channel + +The ftgmac100_open function initializes state for the NCSI +channel. The get link settings function does not return this +data. This caused the link speed, and the duplex value to be returned +incorrectly by the PHY driver (0 Mbps, and duplex off). + +Update the driver to return either the PHY settings when not using +NCSI, or the NCSI values that were assigned when the driver is opened. + +Signed-off-by: Johnathan Mantey +--- + drivers/net/ethernet/faraday/ftgmac100.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c +index 8ed85037f021..a53878eecfc8 100644 +--- a/drivers/net/ethernet/faraday/ftgmac100.c ++++ b/drivers/net/ethernet/faraday/ftgmac100.c +@@ -1218,10 +1218,30 @@ static int ftgmac100_set_pauseparam(struct net_device *netdev, + return 0; + } + ++int ftgmac100_ethtool_get_link_ksettings(struct net_device *netdev, ++ struct ethtool_link_ksettings *cmd) ++{ ++ struct phy_device *phydev = netdev->phydev; ++ struct ftgmac100 *priv = netdev_priv(netdev); ++ int retval = 0; ++ ++ if (phydev) { ++ phy_ethtool_ksettings_get(phydev, cmd); ++ } else if (priv->use_ncsi) { ++ cmd->base.speed = priv->cur_speed; ++ cmd->base.duplex = priv->cur_duplex; ++ cmd->base.autoneg = 0; ++ } else { ++ retval = -ENODEV; ++ } ++ ++ return retval; ++} ++ + static const struct ethtool_ops ftgmac100_ethtool_ops = { + .get_drvinfo = ftgmac100_get_drvinfo, + .get_link = ethtool_op_get_link, +- .get_link_ksettings = phy_ethtool_get_link_ksettings, ++ .get_link_ksettings = ftgmac100_ethtool_get_link_ksettings, + .set_link_ksettings = phy_ethtool_set_link_ksettings, + .nway_reset = phy_ethtool_nway_reset, + .get_ringparam = ftgmac100_get_ringparam, +-- +2.24.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0096-Fix-truncated-WrEndPointConfig-MMIO-command.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0096-Fix-truncated-WrEndPointConfig-MMIO-command.patch new file mode 100644 index 000000000..e2196c629 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0096-Fix-truncated-WrEndPointConfig-MMIO-command.patch @@ -0,0 +1,40 @@ +From 7555448ab0676ea974ef67ef0c8ebe5d68b73d25 Mon Sep 17 00:00:00 2001 +From: "Jason M. Bills" +Date: Tue, 18 Feb 2020 14:17:22 -0800 +Subject: [PATCH] Fix truncated WrEndPointConfig MMIO command + +When address type is 6, the driver is reducing the msg buffer to +the base size and truncating the additional command data. + +This removes the line that sets the msg buffer size to the base +size. The correct buffer size is already set. + +Tested: +Ran this command: +peci_cmds WrEndpointConfigMMIO 6 0 0 0x7e 0x1a 0x0 0x224e0 0x5f5a56 + +and got the full buffer in the driver log: +[ 795.207278] peci_aspeed 1e78b000.peci-bus: HEAD : 0x00011730 +[ 795.212980] TX : c5 00 05 00 00 00 06 00 d0 7e e0 24 02 00 00 00 .........~.$.... +[ 795.220556] TX : 00 00 56 5a 5f 00 a8 ..VZ_.. + +Signed-off-by: Jason M. Bills +--- + drivers/peci/peci-core.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/peci/peci-core.c b/drivers/peci/peci-core.c +index 9aedb74..efb73b0 100644 +--- a/drivers/peci/peci-core.c ++++ b/drivers/peci/peci-core.c +@@ -1040,7 +1040,6 @@ static int peci_cmd_wr_end_pt_cfg(struct peci_adapter *adapter, void *vmsg) + >> 24); /* MSB - DWORD Register Offset */ + if (umsg->params.mmio.addr_type == + PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q) { +- msg->tx_len = PECI_WRENDPTCFG_MMIO_Q_WRITE_LEN_BASE; + msg->tx_buf[14] = (u8)(umsg->params.mmio.offset + >> 32); /* Register Offset */ + msg->tx_buf[15] = (u8)(umsg->params.mmio.offset +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/debug.cfg b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/debug.cfg new file mode 100644 index 000000000..bbc7fa5b6 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/debug.cfg @@ -0,0 +1,2 @@ +CONFIG_DEVMEM = y +CONFIG_DEVMEM_BOOTPARAM = n diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/intel.cfg b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/intel.cfg index 714f40bfd..5f453510a 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/intel.cfg +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/intel.cfg @@ -12,6 +12,7 @@ CONFIG_PECI_CHARDEV=y CONFIG_PECI_ASPEED=y CONFIG_SENSORS_PECI_CPUTEMP=y CONFIG_SENSORS_PECI_DIMMTEMP=y +CONFIG_SENSORS_PECI_CPUPOWER=y CONFIG_CONFIGFS_FS=y CONFIG_BLK_DEV_RAM_SIZE=49152 CONFIG_MAGIC_SYSRQ=y @@ -85,3 +86,4 @@ CONFIG_USB_DYNAMIC_MINORS=n CONFIG_USB_EHCI_HCD=n CONFIG_USB_EHCI_ROOT_HUB_TT=n CONFIG_USB_EHCI_HCD_PLATFORM=n +CONFIG_IPMB_DEVICE_INTERFACE=y diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend index 1898e95f0..b2a81beae 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend @@ -14,7 +14,6 @@ SRC_URI += " \ file://0003-Enable-GPIOE0-and-GPIOE2-pass-through-by-default.patch \ file://0006-Allow-monitoring-of-power-control-input-GPIOs.patch \ file://0007-aspeed-pwm-tacho-change-default-fan-speed.patch \ - file://0008-Report-link-statistics-for-the-NCSI-channel.patch \ file://0014-arm-dts-aspeed-g5-add-espi.patch \ file://0015-New-flash-map-for-intel.patch \ file://0016-Add-ASPEED-SGPIO-driver.patch \ @@ -53,15 +52,11 @@ SRC_URI += " \ file://0070-gpio-aspeed-temporary-fix-for-gpiochip-range-setting.patch \ file://0072-pmbus-add-fault-and-beep-attributes.patch \ file://0073-Add-IO-statistics-to-USB-Mass-storage-gadget.patch \ - file://0074-media-aspeed-refine-HSYNC-VSYNC-polarity-setting-log.patch \ file://0075-Refine-initialization-flow-in-I2C-driver.patch \ - file://0076-media-aspeed-clear-garbage-interrupts.patch \ file://0076-arm-ast2600-add-pwm_tacho-driver-from-aspeed.patch \ file://0077-soc-aspeed-Add-read-only-property-support.patch \ file://0078-Fix-NCSI-driver-issue-caused-by-host-shutdown.patch \ file://0080-i2c-aspeed-filter-garbage-interrupts-out.patch \ - file://0082-ARM-dts-aspeed-g6-add-USB-virtual-hub-fixup.patch \ - file://0083-usb-gadget-aspeed-add-ast2600-compatible-string.patch \ file://0084-ARM-dts-aspeed-g6-add-GFX-node.patch \ file://0085-drm-add-AST2600-GFX-support.patch \ file://0086-ADC-linux-driver-for-AST2600.patch \ @@ -69,6 +64,12 @@ SRC_URI += " \ file://0087-media-aspeed-add-aspeed-ast2600-video-engine-compati.patch \ file://0088-clk-ast2600-enable-ESPICLK-always.patch \ file://0089-ast2600-enable-high-speed-uart-in-kernel.patch \ + file://0090-peci-cpupower-driver-1.patch \ + file://0092-SPI-Quad-IO-driver-support-AST2600.patch \ + file://0093-ipmi-ipmb_dev_int-add-quick-fix-for-raw-I2C-type-reg.patch \ + file://0094-Return-link-speed-and-duplex-settings-for-the-NCSI-c.patch \ + file://0096-Fix-truncated-WrEndPointConfig-MMIO-command.patch \ " SRC_URI += "${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', 'file://0005-128MB-flashmap-for-PFR.patch', '', d)}" +SRC_URI += "${@bb.utils.contains('EXTRA_IMAGE_FEATURES', 'debug-tweaks', 'file://debug.cfg', '', d)}" -- cgit v1.2.3