From 243c130a919c7037b5edd3a8097317340796ce85 Mon Sep 17 00:00:00 2001 From: "Jason M. Bills" Date: Thu, 5 Dec 2019 13:29:56 -0800 Subject: Update to internal 2019-12-05 Signed-off-by: Jason M. Bills --- ...m-dts-add-DTS-for-Intel-ast2500-platforms.patch | 32 +- ...m-dts-add-DTS-for-Intel-ast2600-platforms.patch | 519 +++++++++ .../0001-arm-dts-base-aspeed-g6-dtsi-fixups.patch | 245 +++++ .../0002-Add-Aspeed-fmc-spi-driver.patch | 645 ++++++++++++ ...le-pass-through-on-GPIOE1-and-GPIOE3-free.patch | 86 +- ...GPIOE0-and-GPIOE2-pass-through-by-default.patch | 4 +- ...w-monitoring-of-power-control-input-GPIOs.patch | 42 + .../0015-New-flash-map-for-intel.patch | 2 +- .../0016-Add-ASPEED-SGPIO-driver.patch | 2 +- .../0017-SGPIO-DT-and-pinctrl-fixup.patch | 26 + ...-drivers-to-sync-with-linux-upstreaming-v.patch | 2 +- .../linux-aspeed/0019-Add-I2C-IPMB-support.patch | 2 +- .../0022-Add-AST2500-eSPI-driver.patch | 41 +- .../0026-Add-support-for-new-PECI-commands.patch | 2 +- .../0028-Add-AST2500-JTAG-driver.patch | 4 +- ...ed-Add-Aspeed-UART-routing-control-driver.patch | 55 +- ...d-PWM-driver-which-uses-FTTMR010-timer-IP.patch | 2 +- ...dd-clock-control-logic-into-Aspeed-LPC-BT.patch | 24 +- ...ock-control-logic-into-Aspeed-LPC-SNOOP-d.patch | 15 + ...dd-clock-control-logic-into-Aspeed-LPC-KC.patch | 40 +- .../0051-Add-AST2500-JTAG-device.patch | 2 +- ...dd-Aspeed-SoC-24xx-and-25xx-families-JTAG.patch | 3 +- ...entation-jtag-Add-bindings-for-Aspeed-SoC.patch | 3 +- ...-aspeed-fix-master-pending-state-handling.patch | 135 --- ...-IO-statistics-to-USB-Mass-storage-gadget.patch | 2 +- ...-ast2600-add-pwm_tacho-driver-from-aspeed.patch | 1107 ++++++++++++++++++++ ...NCSI-driver-issue-caused-by-host-shutdown.patch | 70 ++ ...get-aspeed-backport-aspeed-vhub-bug-fixes.patch | 473 +++++++++ ...-i2c-aspeed-filter-garbage-interrupts-out.patch | 64 ++ ...t2600-enable-BCLK-for-PCI-PCIe-bus-always.patch | 32 + ...M-dts-aspeed-g6-add-USB-virtual-hub-fixup.patch | 53 + ...dget-aspeed-add-ast2600-compatible-string.patch | 32 + .../0084-ARM-dts-aspeed-g6-add-GFX-node.patch | 35 + .../0085-drm-add-AST2600-GFX-support.patch | 105 ++ .../0086-ADC-linux-driver-for-AST2600.patch | 271 +++++ .../recipes-kernel/linux/linux-aspeed/intel.cfg | 15 +- .../recipes-kernel/linux/linux-aspeed_%.bbappend | 13 +- 37 files changed, 3991 insertions(+), 214 deletions(-) create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-base-aspeed-g6-dtsi-fixups.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0002-Add-Aspeed-fmc-spi-driver.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0060-i2c-aspeed-fix-master-pending-state-handling.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0076-arm-ast2600-add-pwm_tacho-driver-from-aspeed.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0078-Fix-NCSI-driver-issue-caused-by-host-shutdown.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0079-usb-gadget-aspeed-backport-aspeed-vhub-bug-fixes.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0080-i2c-aspeed-filter-garbage-interrupts-out.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0081-clk-ast2600-enable-BCLK-for-PCI-PCIe-bus-always.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0082-ARM-dts-aspeed-g6-add-USB-virtual-hub-fixup.patch create 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/0084-ARM-dts-aspeed-g6-add-GFX-node.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0085-drm-add-AST2600-GFX-support.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0086-ADC-linux-driver-for-AST2600.patch (limited to 'meta-openbmc-mods/meta-common/recipes-kernel') 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 5400f7bde..a172e8fb2 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 e34e3f667607700dfe0a670bd0e49f98be0d2586 Mon Sep 17 00:00:00 2001 +From 9c7935cd0d6d888e86c33958a7dada2f5afcb543 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,16 +14,16 @@ Signed-off-by: Zhu, Yunge Signed-off-by: Qiang XU Signed-off-by: Chen Yugang --- - arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts | 454 ++++++++++++++++++++++++++ - 1 file changed, 454 insertions(+) + arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts | 470 +++++++++++++++++++++++++ + 1 file changed, 470 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..b3e8d80 +index 0000000..4f3ef45 --- /dev/null +++ b/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts -@@ -0,0 +1,454 @@ +@@ -0,0 +1,470 @@ +/dts-v1/; + +#include "aspeed-g5.dtsi" @@ -31,8 +31,8 @@ index 0000000..b3e8d80 +#include + +/ { -+ model = "Purley BMC"; -+ compatible = "intel,purley-bmc", "aspeed,ast2500"; ++ model = "Intel AST2500 BMC"; ++ compatible = "intel,ast2500-bmc", "aspeed,ast2500"; + + aliases { + serial4 = &uart5; @@ -151,6 +151,18 @@ index 0000000..b3e8d80 + bit-shift = <10>; + read-only; + }; ++ p2a-bridge { ++ offset = <0x180>; ++ bit-mask = <0x1>; ++ bit-shift = <1>; ++ read-only; ++ }; ++ boot-2nd-flash { ++ offset = <0x70>; ++ bit-mask = <0x1>; ++ bit-shift = <17>; ++ read-only; ++ }; + }; +}; + @@ -179,7 +191,7 @@ index 0000000..b3e8d80 + /*P0-P7*/ "","","","","","","","", + /*Q0-Q7*/ "","","","","","","","PWR_DEBUG_N", + /*R0-R7*/ "","XDP_PRST_N","","","","","","", -+ /*S0-S7*/ "","SYSPWROK","RSMRST_N","","","","","", ++ /*S0-S7*/ "REMOTE_DEBUG_ENABLE","SYSPWROK","RSMRST_N","","","","","", + /*T0-T7*/ "","","","","","","","", + /*U0-U7*/ "","","","","","","","", + /*V0-V7*/ "","","","","","","","", @@ -245,6 +257,10 @@ index 0000000..b3e8d80 + status = "okay"; +}; + ++&uart_routing { ++ status = "okay"; ++}; ++ +/** + * SAFS through SPI1 is available only on Wilson Point. + * These pins are used as fan presence checking gpios in WFP 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 new file mode 100644 index 000000000..1ebb67a27 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch @@ -0,0 +1,519 @@ +From 3550c57e80ee30113060efa44d41c08fb29fdd25 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 + +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 +--- + arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts | 495 +++++++++++++++++++++++++ + 1 file changed, 495 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 0000000..a1ea85a +--- /dev/null ++++ b/arch/arm/boot/dts/aspeed-bmc-intel-ast2600.dts +@@ -0,0 +1,495 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/dts-v1/; ++ ++#include "aspeed-g6.dtsi" ++#include ++#include ++ ++/ { ++ model = "AST2600 EVB"; ++ compatible = "aspeed,ast2600"; ++ ++ chosen { ++ stdout-path = &uart5; ++ bootargs = "console=tty0 console=ttyS4,115200n8 root=/dev/ram rw init=/linuxrc"; ++ }; ++ ++ memory@80000000 { ++ device_type = "memory"; ++ reg = <0x80000000 0x40000000>; ++ }; ++ ++ reserved-memory { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ gfx_memory: framebuffer { ++ size = <0x01000000>; ++ alignment = <0x01000000>; ++ compatible = "shared-dma-pool"; ++ reusable; ++ }; ++ }; ++ ++ reserved-memory { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ video_memory: video { ++ size = <0x04000000>; ++ alignment = <0x01000000>; ++ compatible = "shared-dma-pool"; ++ no-map; ++ }; ++ }; ++ ++ iio-hwmon { ++ 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>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ identify { ++ default-state = "off"; ++ gpios = <&gpio1 ASPEED_GPIO(B, 7) GPIO_ACTIVE_LOW>; ++ }; ++ ++ status_amber { ++ default-state = "off"; ++ gpios = <&gpio1 ASPEED_GPIO(G, 3) GPIO_ACTIVE_LOW>; ++ }; ++ ++ status_green { ++ default-state = "keep"; ++ gpios = <&gpio1 ASPEED_GPIO(G, 2) GPIO_ACTIVE_LOW>; ++ }; ++ }; ++/* ++ beeper { ++ compatible = "pwm-beeper"; ++ pwms = <&timer 7 1000000 0>; ++ }; */ ++}; ++ ++&fmc { ++ status = "okay"; ++ flash: m25p80@0 { ++ compatible = "m25p80", "jedec,spi-nor"; ++ reg = <0x0>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ spi-max-frequency = <10000000>; ++ m25p,fast-read; ++#include "openbmc-flash-layout-intel-64MB.dtsi" ++ }; ++}; ++ ++&espi { ++ status = "okay"; ++}; ++ ++&peci0 { ++ status = "okay"; ++ gpios = <&gpio0 ASPEED_GPIO(F, 6) 0>; ++}; ++ ++&syscon { ++ uart-clock-high-speed; ++ status = "okay"; ++}; ++ ++#if 0 ++ GPIO Alias: (runtime alias -> schematic name) ++ ID_BUTTON -> FP_ID_BTN_N ++ CPU_CATERR -> FM_PLT_BMC_THERMTRIP_N ++ PCH_BMC_THERMTRIP -> FM_PLT_BMC_THERMTRIP_N ++ RESET_BUTTON -> FP_BMC_RST_BTN_N ++ RESET_OUT -> RST_BMC_RSTBTN_OUT_R_N ++ POWER_BUTTON -> FP_BMC_PWR_BTN_R_N ++ POWER_OUT -> FM_BMC_PWR_BTN_N ++ PREQ_N -> DBP_ASD_BMC_PREQ_R_N ++ POST_COMPLETE -> FM_BIOS_POST_CMPLT_BMC_N ++ CPU_ERR0 -> FM_CPU_ERR0_LVT3_N ++ CPU_ERR1 -> FM_CPU_ERR1_LVT3_N ++ CPU_ERR2 -> FM_CPU_ERR2_LVT3_N ++ DEBUG_EN_N -> FM_JTAG_TCK_MUX_SEL_R ++ NMI_OUT -> IRQ_BMC_CPU_NMI_R ++ PLTRST_N -> RST_PLTRST_BMC_N ++ PRDY_N -> DBP_ASD_BMC_PRDY_R_N ++ PWR_DEBUG_N -> ++ XDP_PRST_N -> ++ SYSPWROK -> ++ RSMRST_N -> ++ SIO_S3 -> FM_SLPS3_R_N ++ SIO_S5 -> FM_SLPS4_R_N ++ SIO_ONCONTROL -> FM_BMC_ONCTL_R_N ++ SIO_POWER_GOOD -> PWRGD_CPU0_LVC3_R ++ PS_PWROK -> PWRGD_BMC_PS_PWROK_R ++ P3VBAT_BRIDGE_EN -> ++ TCK_MUX_SEL -> ++ SMI -> IRQ_SMI_ACTIVE_BMC_N ++ NMI_BUTTON -> FP_NMI_BTN_N ++#endif ++&gpio0 { ++ status = "okay"; ++ /* Enable GPIOP0 and GPIOP2 pass-through by default */ ++ /* pinctrl-names = "pass-through"; ++ pinctrl-0 = <&pinctrl_thru0_default ++ &pinctrl_thru1_default>; */ ++ 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","","", ++ /*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","","","","","","", ++ /*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", ++ /*N0-N7*/ "SPB_CTS_N","SPB_DCD_N","SPB_DSR_N","PU_SPB_RI_N","SPB_DTR_N","SPB_RTS_N","SPB_SOUT","SPB_SIN", ++ /*O0-O7*/ "FAN_BMC_PWM0","FAN_BMC_PWM1","FAN_BMC_PWM2","FAN_BMC_PWM3","FAN_BMC_PWM4","FAN_BMC_PWM5","NMI_BUTTON","SPEAKER_BMC_R", ++ /*P0-P7*/ "RESET_BUTTON","RESET_OUT","POWER_BUTTON","POWER_OUT","FAN_BMC_PWM6","FAN_BMC_PWM7","FAN_BMC_PWM8","FAN_BMC_PWM9", ++ /*Q0-Q7*/ "FAN_BMC_TACH0","FAN_BMC_TACH1","FAN_BMC_TACH2","FAN_BMC_TACH3","FAN_BMC_TACH4","FAN_BMC_TACH5","FAN_BMC_TACH6","FAN_BMC_TACH7", ++ /*R0-R7*/ "FAN_BMC_TACH8","FAN_BMC_TACH9","","","","","","", ++ /*S0-S7*/ "RST_BMC_PCIE_MUX_N","FM_BMC_EUP_LOT6_N","","","","A_P3V_BAT_SCALED_EN","REMOTE_DEBUG_ENABLE","FM_PCHHOT_N", ++ /*T0-T7*/ "A_P12V_PSU_SCALED","A_P12V_AUX_SCALED","A_P3V3_SCALED","A_P5V_SCALED","A_PVNN_PCH_AUX_SENSOR","A_P1V05_PCH_AUX_SENSOR","A_P1V8_AUX_SENSOR","A_P3V_BAT_SCALED", ++ /*U0-U7*/ "A_PVCCIN_CPU0_SENSOR","A_PVCCIN_CPU1_SENSOR","A_PVCCINFAON_CPU0_SENSOR","A_PVCCINFAON_CPU1_SENSOR","A_PVCCFA_EHV_FIVRA_CPU0_SENSOR","A_PVCCFA_EHV_FIVRA_CPU1_SENSOR","A_PVCCD_HV_CPU0_SENSOR","A_PVCCD_HV_CPU1_SENSOR", ++ /*V0-V7*/ "SIO_S3","SIO_S5","TP_BMC_SIO_PWREQ_N","SIO_ONCONTROL","SIO_POWER_GOOD","LED_BMC_HB_LED_N","FM_BMC_SUSACK_N","", ++ /*W0-W7*/ "LPC_LAD0_ESPI_R_IO0","LPC_LAD1_ESPI_R_IO1","LPC_LAD2_ESPI_R_IO2","LPC_LAD3_ESPI_R_IO3","CLK_24M_66M_LPC0_ESPI_BMC","LPC_LFRAME_N_ESPI_CS0_BMC_N","IRQ_LPC_SERIRQ_ESPI_ALERT_N","RST_LPC_LRST_ESPI_RST_BMC_R_N", ++ /*X0-X7*/ "","SMI","POST_COMPLETE","","","","","", ++ /*Y0-Y7*/ "","IRQ_SML0_ALERT_BMC_R2_N","","IRQ_SML1_PMBUS_BMC_ALERT_N","SPI_BMC_BOOT_R_IO2","SPI_BMC_BOOT_R_IO3","PU_SPI_BMC_BOOT_ABR","PU_SPI_BMC_BOOT_WP_N", ++ /*Z0-Z7*/ "PWRGD_P3V3_RISER1","PWRGD_P3V3_RISER2","","HW_STRAP_5","HW_STRAP_6","HW_STRAP_7","HW_STRAP_2","HW_STRAP_3"; ++}; ++ ++&gpio1 { ++ status = "disabled"; ++ gpio-line-names = /* GPIO18 A-E */ ++ /*A0-A7*/ "","","RST_EMMC_BMC_R_N","FM_SYS_FAN6_PRSNT_D_N","FM_SYS_FAN0_PRSNT_D_N","FM_SYS_FAN1_PRSNT_D_N","FM_SYS_FAN2_PRSNT_D_N","FM_SYS_FAN3_PRSNT_D_N", ++ /*B0-B7*/ "FM_SYS_FAN4_PRSNT_D_N","FM_SYS_FAN5_PRSNT_D_N","","FM_SYS_FAN7_PRSNT_D_N","RGMII_BMC_RMM4_TX_R_CLK","RGMII_BMC_RMM4_TX_R_CTRL","RGMII_BMC_RMM4_R_TXD0","RGMII_BMC_RMM4_R_TXD1", ++ /*C0-C7*/ "RGMII_BMC_RMM4_R_TXD2","RGMII_BMC_RMM4_R_TXD3","RGMII_BMC_RMM4_RX_CLK","RGMII_BMC_RMM4_RX_CTRL","RGMII_BMC_RMM4_RXD0","RGMII_BMC_RMM4_RXD1","RGMII_BMC_RMM4_RXD2","RGMII_BMC_RMM4_RXD3", ++ /*D0-D7*/ "EMMC_BMC_R_CLK","EMMC_BMC_R_CMD","EMMC_BMC_R_DATA0","EMMC_BMC_R_DATA1","EMMC_BMC_R_DATA2","EMMC_BMC_R_DATA3","EMMC_BMC_CD_N","EMMC_BMC_WP_N", ++ /*E0-E3*/ "EMMC_BMC_R_DATA4","EMMC_BMC_R_DATA5","EMMC_BMC_R_DATA6","EMMC_BMC_R_DATA7"; ++}; ++ ++&sgpio { ++ status = "okay"; ++ gpio-line-names = ++ /* SGPIO output lines */ ++ /*OA0-OA7*/ "","","","","","","","", ++ /*OB0-OB7*/ "LED_CPU1_CH1_DIMM1_FAULT","LED_CPU1_CH1_DIMM2_FAULT","LED_CPU1_CH2_DIMM1_FAULT","LED_CPU1_CH2_DIMM2_FAULT","LED_CPU1_CH3_DIMM1_FAULT","LED_CPU1_CH3_DIMM2_FAULT","LED_CPU1_CH4_DIMM1_FAULT","LED_CPU1_CH4_DIMM2_FAULT", ++ /*OC0-OC7*/ "LED_CPU1_CH5_DIMM1_FAULT","LED_CPU1_CH5_DIMM2_FAULT","LED_CPU1_CH6_DIMM1_FAULT","LED_CPU1_CH6_DIMM2_FAULT","LED_FAN1_FAULT","LED_FAN2_FAULT","LED_FAN3_FAULT","LED_FAN4_FAULT", ++ /*OD0-OD7*/ "LED_FAN5_FAULT","LED_FAN6_FAULT","LED_FAN7_FAULT","LED_FAN8_FAULT","LED_CPU2_CH1_DIMM1_FAULT","LED_CPU1_CH1_DIMM2_FAULT","LED_CPU2_CH2_DIMM1_FAULT","LED_CPU2_CH2_DIMM2_FAULT", ++ /*OE0-OE7*/ "LED_CPU2_CH3_DIMM1_FAULT","LED_CPU2_CH3_DIMM2_FAULT","LED_CPU2_CH4_DIMM1_FAULT","LED_CPU2_CH4_DIMM2_FAULT","LED_CPU2_CH5_DIMM1_FAULT","LED_CPU2_CH5_DIMM2_FAULT","LED_CPU2_CH6_DIMM1_FAULT","LED_CPU2_CH6_DIMM2_FAULT", ++ /*OF0-OF7*/ "LED_CPU3_CH1_DIMM1_FAULT","LED_CPU3_CH1_DIMM2_FAULT","LED_CPU3_CH2_DIMM1_FAULT","LED_CPU3_CH2_DIMM2_FAULT","LED_CPU3_CH3_DIMM1_FAULT","LED_CPU3_CH3_DIMM2_FAULT","LED_CPU3_CH4_DIMM1_FAULT","LED_CPU3_CH4_DIMM2_FAULT", ++ /*OG0-OG7*/ "LED_CPU3_CH5_DIMM1_FAULT","LED_CPU3_CH5_DIMM2_FAULT","LED_CPU3_CH6_DIMM1_FAULT","LED_CPU3_CH6_DIMM2_FAULT","LED_CPU4_CH1_DIMM1_FAULT","LED_CPU4_CH1_DIMM2_FAULT","LED_CPU4_CH2_DIMM1_FAULT","LED_CPU4_CH2_DIMM2_FAULT", ++ /*OH0-OH7*/ "LED_CPU4_CH3_DIMM1_FAULT","LED_CPU4_CH3_DIMM2_FAULT","LED_CPU4_CH4_DIMM1_FAULT","LED_CPU4_CH4_DIMM2_FAULT","LED_CPU4_CH5_DIMM1_FAULT","LED_CPU4_CH5_DIMM2_FAULT","LED_CPU4_CH6_DIMM1_FAULT","LED_CPU4_CH6_DIMM2_FAULT", ++ /*OI0-OI7*/ "","","","","","","","", ++ /*OJ0-OJ7*/ "","","","","","","","", ++ /*DUMMY*/ "","","","","","","","", ++ /*DUMMY*/ "","","","","","","","", ++ ++ /* SGPIO input lines */ ++ /* Some lines have been renamed from the net names: ++ CPU1_PRESENCE -> FM_CPU0_SKTOCC_LVT3_N ++ CPU1_THERMTRIP -> H_CPU0_THERMTRIP_LVC1_N ++ CPU1_VRHOT -> IRQ_CPU0_VRHOT_N ++ CPU1_FIVR_FAULT -> H_CPU0_MON_FAIL_PLD_LVC1_N ++ CPU1_MEM_ABCD_VRHOT -> ?? ++ CPU1_MEM_EFGH_VRHOT -> ?? ++ CPU2_PRESENCE -> FM_CPU1_SKTOCC_LVT3_N ++ CPU2_THERMTRIP -> H_CPU1_THERMTRIP_LVC1_N ++ CPU2_VRHOT -> IRQ_CPU1_VRHOT_N ++ CPU2_FIVR_FAULT -> H_CPU1_MON_FAIL_PLD_LVC1_N ++ CPU2_MEM_ABCD_VRHOT -> ?? ++ CPU2_MEM_EFGH_VRHOT -> ?? ++ ++ /*IA0-IA7*/ "CPU1_PRESENCE","CPU1_THERMTRIP","CPU1_VRHOT","CPU1_FIVR_FAULT","IRQ_CPU0_MEM_VRHOT_N","H_CPU0_MEMHOT_OUT_LVC1_N","FM_CPU0_PROC_ID0","FM_CPU0_PROC_ID1", ++ /*IB0-IB7*/ "WCPU_MISMATCH","IRQ_PSYS_CRIT_N","CPU2_PRESENCE","CPU2_THERMTRIP","CPU2_VRHOT","CPU2_FIVR_FAULT","IRQ_CPU1_MEM_VRHOT_N","H_CPU1_MEMHOT_OUT_LVC1_N", ++ /*IC0-IC7*/ "FM_CPU1_PROC_ID0","FM_CPU1_PROC_ID1","","","","","","", ++ /*ID0-ID7*/ "","","","","","","","", ++ /*IE0-IE7*/ "","","","","","","","", ++ /*IF0-IF7*/ "FPGA_REV_TEST_0","FPGA_REV_TEST_1","FPGA_REV_TEST_2","FPGA_REV_TEST_3","FPGA_REV_TEST_4","FPGA_REV_TEST_5","FPGA_REV_TEST_6","FPGA_REV_TEST_7", ++ /*IG0-IG7*/ "FPGA_REV_0","FPGA_REV_1","FPGA_REV_2","FPGA_REV_3","FPGA_REV_4","FPGA_REV_5","FPGA_REV_6","FPGA_REV_7", ++ /*IH0-IH7*/ "","WMEMX_PWR_FLT","WCPUX_MEM_PWR_FLT","PWRGD_P3V3_FF","WPSU_PWR_FLT","","","WPCH_PWR_FLT", ++ /*II0-II7*/ "FM_CPU0_PKGID0","FM_CPU0_PKGID1","FM_CPU0_PKGID2","H_CPU0_MEMTRIP_LVC1_N","FM_CPU1_PKGID0","FM_CPU1_PKGID1","FM_CPU1_PKGID2","H_CPU1_MEMTRIP_LVC1_N", ++ /*IJ0-IJ7*/ "","","","","","","",""; ++}; ++ ++&kcs3 { ++ kcs_addr = <0xCA2>; ++ status = "okay"; ++}; ++ ++&kcs4 { ++ kcs_addr = <0xCA4>; ++ status = "okay"; ++}; ++ ++&lpc_sio { ++ status = "okay"; ++}; ++ ++&lpc_snoop { ++ snoop-ports = <0x80>; ++ status = "okay"; ++}; ++ ++&mbox { ++ status = "okay"; ++}; ++ ++&mdio1 { ++ status = "okay"; ++ ++ ethphy1: ethernet-phy@0 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0>; ++ }; ++}; ++ ++&mac1 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_rgmii2_default>; ++ clocks = <&syscon ASPEED_CLK_GATE_MAC2CLK>, ++ <&syscon ASPEED_CLK_GATE_MAC2RCLK>; ++ clock-names = "MACCLK", "RCLK"; ++ phy-mode = "rgmii"; ++ phy-handle = <ðphy1>; ++}; ++ ++&mdio2 { ++ status = "okay"; ++ ++ ethphy2: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0>; ++ }; ++}; ++ ++&adc0 { ++ status = "okay"; ++}; ++ ++&adc1 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++ // Workaround for A0 ++ compatible = "snps,dw-apb-uart"; ++ pinctrl-0 = <&pinctrl_txd1_default ++ &pinctrl_rxd1_default ++ &pinctrl_nrts1_default ++ &pinctrl_ndtr1_default ++ &pinctrl_ndsr1_default ++ &pinctrl_ncts1_default ++ &pinctrl_ndcd1_default ++ &pinctrl_nri1_default>; ++}; ++ ++&uart2 { ++ status = "okay"; ++ // Workaround for A0 ++ compatible = "snps,dw-apb-uart"; ++ pinctrl-0 = <&pinctrl_txd2_default ++ &pinctrl_rxd2_default ++ &pinctrl_nrts2_default ++ &pinctrl_ndtr2_default ++ &pinctrl_ndsr2_default ++ &pinctrl_ncts2_default ++ &pinctrl_ndcd2_default ++ &pinctrl_nri2_default>; ++}; ++ ++&uart3 { ++ status = "okay"; ++ // Workaround for A0 ++ compatible = "snps,dw-apb-uart"; ++ pinctrl-0 = <>; ++}; ++ ++&uart4 { ++ status = "okay"; ++ // Workaround for A0 ++ compatible = "snps,dw-apb-uart"; ++ pinctrl-0 = <>; ++}; ++ ++&uart5 { ++ status = "okay"; ++ // Workaround for A0 ++ compatible = "snps,dw-apb-uart"; ++}; ++ ++&uart_routing { ++ status = "okay"; ++}; ++ ++&emmc_controller{ ++ status = "okay"; ++}; ++ ++&emmc { ++ non-removable; ++ bus-width = <4>; ++ max-frequency = <52000000>; ++}; ++ ++&i2c0 { ++ /* SMB_CHASSENSOR_STBY_LVC3 */ ++ multi-master; ++ status = "okay"; ++}; ++ ++&i2c4 { ++ /* SMB_HSBP_STBY_LVC3_R */ ++ multi-master; ++ status = "okay"; ++ ++ hsbp0@10 { ++ compatible = "slave-mqueue"; ++ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>; ++ }; ++}; ++ ++&i2c5 { ++ /* SMB_SMLINK0_STBY_LVC3_R2 */ ++ bus-frequency = <1000000>; ++ multi-master; ++ status = "okay"; ++ ++ smlink0@10 { ++ compatible = "slave-mqueue"; ++ reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>; ++ }; ++}; ++ ++&i2c6 { ++ /* SMB_TEMPSENSOR_STBY_LVC3_R */ ++ multi-master; ++ status = "okay"; ++}; ++ ++&i2c7 { ++ /* SMB_PMBUS_SML1_STBY_LVC3_R */ ++ multi-master; ++ #retries = <3>; ++ ++ status = "okay"; ++}; ++ ++&i2c8 { ++ /* SMB_PCIE_STBY_LVC3_R */ ++ multi-master; ++ status = "okay"; ++}; ++ ++&i2c9 { ++ /* SMB_HOST_STBY_BMC_LVC3_R */ ++ multi-master; ++ status = "okay"; ++}; ++ ++&i2c12 { ++ /* SMB_CPU_PIROM */ ++ multi-master; ++ status = "okay"; ++}; ++ ++&i2c13 { ++ /* SMB_IPMB_STBY_LVC3_R */ ++ multi-master; ++ status = "okay"; ++}; ++ ++&i3c0 { ++ /* I3C_SPD_DDRABCD_CPU0_BMC ; FIXME: i3c driver hangs kernel on probe...*/ ++ status = "disabled"; ++}; ++ ++&i3c1 { ++ /* I3C_SPD_DDREFGH_CPU0_BMC */ ++ status = "disabled"; ++}; ++ ++&i3c2 { ++ /* I3C_SPD_DDRABCD_CPU1_BMC */ ++ status = "disabled"; ++}; ++ ++&i3c3 { ++ /* I3C_SPD_DDREFGH_CPU1_BMC */ ++ status = "disabled"; ++}; ++ ++&gfx { ++ status = "okay"; ++ memory-region = <&gfx_memory>; ++}; ++ ++&pwm_tacho { ++ status = "disabled"; /* FIXME: disabled because of bug in driver */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default ++ &pinctrl_pwm2_default &pinctrl_pwm3_default ++ &pinctrl_pwm4_default &pinctrl_pwm5_default ++ &pinctrl_pwm12g1_default &pinctrl_pwm13g1_default ++ &pinctrl_pwm14g1_default &pinctrl_pwm15g1_default>; ++ ++ fan@0 { ++ reg = <0x00>; ++ aspeed,fan-tach-ch = /bits/ 8 <0x00 0x01>; ++ }; ++ fan@1 { ++ reg = <0x01>; ++ aspeed,fan-tach-ch = /bits/ 8 <0x02 0x03>; ++ }; ++ fan@2 { ++ reg = <0x02>; ++ aspeed,fan-tach-ch = /bits/ 8 <0x04 0x05>; ++ }; ++ fan@3 { ++ reg = <0x03>; ++ aspeed,fan-tach-ch = /bits/ 8 <0x06 0x07>; ++ }; ++ fan@4 { ++ reg = <0x04>; ++ aspeed,fan-tach-ch = /bits/ 8 <0x08 0x09>; ++ }; ++ fan@5 { ++ reg = <0x05>; ++ aspeed,fan-tach-ch = /bits/ 8 <0x0A 0x0B>; ++ }; ++ fan@6 { ++ reg = <0x06>; ++ aspeed,fan-tach-ch = /bits/ 8 <0x18 0x19>; ++ }; ++ fan@7 { ++ reg = <0x07>; ++ aspeed,fan-tach-ch = /bits/ 8 <0x1A 0x1B>; ++ }; ++ fan@8 { ++ reg = <0x08>; ++ aspeed,fan-tach-ch = /bits/ 8 <0x1C 0x1D>; ++ }; ++ fan@9 { ++ reg = <0x09>; ++ aspeed,fan-tach-ch = /bits/ 8 <0x1E 0x1F>; ++ }; ++}; ++ ++&vhub { ++ status = "okay"; ++}; +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-base-aspeed-g6-dtsi-fixups.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-base-aspeed-g6-dtsi-fixups.patch new file mode 100644 index 000000000..4fc3d8582 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0001-arm-dts-base-aspeed-g6-dtsi-fixups.patch @@ -0,0 +1,245 @@ +From 58d4715d6ac08a20f68044875fdc3afaf75ee2a1 Mon Sep 17 00:00:00 2001 +From: Vernon Mauery +Date: Thu, 12 Sep 2019 15:55:39 +0800 +Subject: [PATCH] arm: dts: base aspeed g6 dtsi fixups + +Additions to the base g6 dtsi file for Aspeed ast2600 systems. +This mostly includes entries for the drivers that are not upstream. + +Signed-off-by: Vernon Mauery +--- + arch/arm/boot/dts/aspeed-g6.dtsi | 207 +++++++++++++++++++++- + include/dt-bindings/clock/ast2600-clock.h | 8 + + 2 files changed, 213 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index 8ac435b3dbde..5de3af52830d 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -28,6 +28,13 @@ + i2c13 = &i2c13; + i2c14 = &i2c14; + i2c15 = &i2c15; ++ i3c0 = &i3c0; ++ i3c1 = &i3c1; ++ i3c2 = &i3c2; ++ i3c3 = &i3c3; ++ i3c4 = &i3c4; ++ i3c5 = &i3c5; ++ peci0 = &peci0; + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; +@@ -273,11 +284,21 @@ + quality = <100>; + }; + ++ adc: adc@1e6e9000 { ++ compatible = "aspeed,ast2500-adc"; ++ reg = <0x1e6e9000 0x100>; ++ clocks = <&syscon ASPEED_CLK_APB2>; ++ interrupts = ; ++ resets = <&syscon ASPEED_RESET_ADC>; ++ #io-channel-cells = <1>; ++ status = "disabled"; ++ }; ++ + gpio0: gpio@1e780000 { + #gpio-cells = <2>; + gpio-controller; + compatible = "aspeed,ast2600-gpio"; +- reg = <0x1e780000 0x800>; ++ reg = <0x1e780000 0x200>; + interrupts = ; + gpio-ranges = <&pinctrl 0 0 208>; + ngpios = <208>; +@@ -290,7 +311,7 @@ + #gpio-cells = <2>; + gpio-controller; + compatible = "aspeed,ast2600-gpio"; +- reg = <0x1e780800 0x800>; ++ reg = <0x1e780800 0x200>; + interrupts = ; + gpio-ranges = <&pinctrl 0 208 36>; + ngpios = <36>; +@@ -338,6 +407,20 @@ + status = "disabled"; + }; + ++ peci: bus@1e78b000 { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x0 0x1e78b000 0x60>; ++ }; ++ ++ i3c: bus@1e7a0000 { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0x1e7a0000 0x8000>; ++ }; ++ + lpc: lpc@1e789000 { + compatible = "aspeed,ast2600-lpc", "simple-mfd"; + reg = <0x1e789000 0x1000>; +@@ -426,6 +509,20 @@ + sio_regs: regs { + compatible = "aspeed,bmc-misc"; + }; ++ ++ lpc_sio: lpc-sio@100 { ++ compatible = "aspeed,ast2500-lpc-sio"; ++ reg = <0x100 0x20>; ++ clocks = <&syscon ASPEED_CLK_GATE_LCLK>; ++ status = "disabled"; ++ }; ++ ++ mbox: mbox@180 { ++ compatible = "aspeed,ast2600-mbox"; ++ reg = <0x180 0x5c>; ++ interrupts = ; ++ #mbox-cells = <1>; ++ }; + }; + }; + +@@ -529,6 +626,24 @@ + + #include "aspeed-g6-pinctrl.dtsi" + ++&peci { ++ peci0: peci-bus@0 { ++ compatible = "aspeed,ast2500-peci"; ++ reg = <0x0 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clocks = <&syscon ASPEED_CLK_GATE_REF0CLK>, <&syscon ASPEED_CLK_AHB>; ++ resets = <&syscon ASPEED_RESET_PECI>; ++ clock-frequency = <24000000>; ++ msg-timing = <1>; ++ addr-timing = <1>; ++ rd-sampling-point = <8>; ++ cmd-timeout-ms = <1000>; ++ status = "disabled"; ++ }; ++}; ++ + &i2c { + i2c0: i2c-bus@40 { + #address-cells = <1>; +@@ -770,3 +885,91 @@ + status = "disabled"; + }; + }; ++ ++&i3c { ++ i3c0: i3c0@2000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #interrupt-cells = <1>; ++ reg = <0x2000 0x1000>; ++ compatible = "snps,dw-i3c-master-1.00a"; ++ clocks = <&syscon ASPEED_CLK_APB2>; ++ resets = <&syscon ASPEED_RESET_I3C0>; ++ bus-frequency = <100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ i3c1: i3c1@3000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #interrupt-cells = <1>; ++ reg = <0x3000 0x1000>; ++ compatible = "snps,dw-i3c-master-1.00a"; ++ clocks = <&syscon ASPEED_CLK_APB2>; ++ resets = <&syscon ASPEED_RESET_I3C1>; ++ bus-frequency = <100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ i3c2: i3c2@4000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #interrupt-cells = <1>; ++ reg = <0x4000 0x1000>; ++ compatible = "snps,dw-i3c-master-1.00a"; ++ clocks = <&syscon ASPEED_CLK_APB2>; ++ resets = <&syscon ASPEED_RESET_I3C2>; ++ bus-frequency = <100000>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i3c3_default>; ++ status = "disabled"; ++ }; ++ ++ i3c3: i3c3@5000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #interrupt-cells = <1>; ++ reg = <0x5000 0x1000>; ++ compatible = "snps,dw-i3c-master-1.00a"; ++ clocks = <&syscon ASPEED_CLK_APB2>; ++ resets = <&syscon ASPEED_RESET_I3C3>; ++ bus-frequency = <100000>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i3c4_default>; ++ status = "disabled"; ++ }; ++ ++ i3c4: i3c4@6000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #interrupt-cells = <1>; ++ reg = <0x6000 0x1000>; ++ compatible = "snps,dw-i3c-master-1.00a"; ++ clocks = <&syscon ASPEED_CLK_APB2>; ++ resets = <&syscon ASPEED_RESET_I3C4>; ++ bus-frequency = <100000>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i3c5_default>; ++ status = "disabled"; ++ }; ++ ++ i3c5: i3c5@7000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #interrupt-cells = <1>; ++ reg = <0x7000 0x1000>; ++ compatible = "snps,dw-i3c-master-1.00a"; ++ clocks = <&syscon ASPEED_CLK_APB2>; ++ resets = <&syscon ASPEED_RESET_I3C5>; ++ bus-frequency = <100000>; ++ interrupts = ; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i3c6_default>; ++ status = "disabled"; ++ }; ++}; +diff --git a/include/dt-bindings/clock/ast2600-clock.h b/include/dt-bindings/clock/ast2600-clock.h +index ac567fc84a87..94350356cfb1 100644 +--- a/include/dt-bindings/clock/ast2600-clock.h ++++ b/include/dt-bindings/clock/ast2600-clock.h +@@ -92,6 +92,14 @@ + /* Only list resets here that are not part of a gate */ + #define ASPEED_RESET_ADC 55 + #define ASPEED_RESET_JTAG_MASTER2 54 ++#define ASPEED_RESET_I3C7 47 ++#define ASPEED_RESET_I3C6 46 ++#define ASPEED_RESET_I3C5 45 ++#define ASPEED_RESET_I3C4 44 ++#define ASPEED_RESET_I3C3 43 ++#define ASPEED_RESET_I3C2 42 ++#define ASPEED_RESET_I3C1 41 ++#define ASPEED_RESET_I3C0 40 + #define ASPEED_RESET_I3C_DMA 39 + #define ASPEED_RESET_PWM 37 + #define ASPEED_RESET_PECI 36 +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0002-Add-Aspeed-fmc-spi-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0002-Add-Aspeed-fmc-spi-driver.patch new file mode 100644 index 000000000..08e350c15 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0002-Add-Aspeed-fmc-spi-driver.patch @@ -0,0 +1,645 @@ +From 1365492683b47f63d470d0666fee258a5c7ca3c3 Mon Sep 17 00:00:00 2001 +From: Vernon Mauery +Date: Thu, 12 Sep 2019 15:26:08 -0700 +Subject: [PATCH 04/52] Add Aspeed fmc-spi driver + +Add the Aspeed fmc-spi driver from the Apeed SDK v5.02 + +Signed-off-by: Vernon Mauery +--- + arch/arm/boot/dts/aspeed-g6.dtsi | 43 ++- + drivers/spi/Kconfig | 6 + + drivers/spi/Makefile | 1 + + drivers/spi/fmc_spi.c | 530 +++++++++++++++++++++++++++++++ + 4 files changed, 579 insertions(+), 1 deletion(-) + create mode 100644 drivers/spi/fmc_spi.c + +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index 42f644ac8111..1aab48fbf49e 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -90,7 +90,7 @@ + <0x40464000 0x2000>, + <0x40466000 0x2000>; + }; +- ++#if 1 + fmc: spi@1e620000 { + reg = < 0x1e620000 0xc4 + 0x20000000 0x10000000 >; +@@ -169,6 +169,47 @@ + status = "disabled"; + }; + }; ++#else ++ spi0: spi@1e620000 { ++ /* reg : cs0 : cs1 : cs2 */ ++ reg = <0x1e620000 0x100 ++ 0x20000000 0x40 ++ 0x28000000 0x40>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "aspeed,fmc-spi"; ++ clocks = <&syscon ASPEED_CLK_AHB>; ++ status = "disable"; ++ number_of_chip_select = /bits/ 16 <2>; ++ interrupts = ; ++ }; ++ ++ spi1: spi1@1e630000 { ++ /* reg : cs0 : cs1 */ ++ reg = <0x1e630000 0x100 ++ 0x30000000 0x20 ++ 0x32000000 0x20>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "aspeed,fmc-spi"; ++ clocks = <&syscon ASPEED_CLK_AHB>; ++ status = "disable"; ++ number_of_chip_select = /bits/ 16 <2>; ++ }; ++ ++ spi2: spi2@1e631000 { ++ /* reg : cs0 : cs1 */ ++ reg = <0x1e631000 0x100 ++ 0x38000000 0x20 ++ 0x3A000000 0x20>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "aspeed,fmc-spi"; ++ clocks = <&syscon ASPEED_CLK_AHB>; ++ status = "disable"; ++ number_of_chip_select = /bits/ 16 <2>; ++ }; ++#endif + + mdio0: mdio@1e650000 { + compatible = "aspeed,ast2600-mdio"; +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index 6ee514fd0920..9f32c31ffa3c 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -57,6 +57,12 @@ config SPI_MEM + + comment "SPI Master Controller Drivers" + ++config SPI_FMC ++ tristate "Aspeed FMC SPI Controller" ++ depends on ARCH_ASPEED ++ help ++ This selects a driver for the AST FMC SPI Controller ++ + config SPI_ALTERA + tristate "Altera SPI Controller" + help +diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile +index adbebee93a75..224b9b71e29c 100644 +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -13,6 +13,7 @@ obj-$(CONFIG_SPI_SPIDEV) += spidev.o + obj-$(CONFIG_SPI_LOOPBACK_TEST) += spi-loopback-test.o + + # SPI master controller drivers (bus) ++obj-$(CONFIG_SPI_FMC) += fmc_spi.o + obj-$(CONFIG_SPI_ALTERA) += spi-altera.o + obj-$(CONFIG_SPI_ARMADA_3700) += spi-armada-3700.o + obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o +diff --git a/drivers/spi/fmc_spi.c b/drivers/spi/fmc_spi.c +new file mode 100644 +index 000000000000..f21f7a00496e +--- /dev/null ++++ b/drivers/spi/fmc_spi.c +@@ -0,0 +1,530 @@ ++/* ++ * fmc_spi.c - FMC SPI driver for the Aspeed SoC ++ * ++ * Copyright (C) ASPEED Technology Inc. ++ * Ryan Chen ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/******************************************************************************/ ++/* AST_SPI_CONFIG 0x00 : SPI00 CE Type Setting Register */ ++#define AST_G5_SPI_CONF_CE1_WEN (0x1 << 17) ++#define AST_G5_SPI_CONF_CE0_WEN (0x1 << 16) ++ ++#define SPI_CONF_CE0_WEN (0x1) ++ ++/* Register offsets */ ++#define FMC_SPI_CONFIG 0x00 ++#define FMC_SPI_CTRL 0x04 ++#define FMC_SPI_DMA_STS 0x08 ++ ++#define FMC_SPI_CE0_CTRL 0x10 ++#define FMC_SPI_CE1_CTRL 0x14 ++ ++#define AST_SPI_DMA_CTRL 0x80 ++#define AST_SPI_DMA_FLASH_BASE 0x84 ++#define AST_SPI_DMA_DRAM_BASE 0x88 ++#define AST_SPI_DMA_LENGTH 0x8c ++ ++/* AST_FMC_CONFIG 0x00 : FMC00 CE Type Setting Register */ ++#define FMC_CONF_LAGACY_DIS (0x1 << 31) ++#define FMC_CONF_CE1_WEN (0x1 << 17) ++#define FMC_CONF_CE0_WEN (0x1 << 16) ++#define FMC_CONF_CE1_SPI (0x2 << 2) ++#define FMC_CONF_CE0_SPI (0x2) ++ ++/* FMC_SPI_CTRL : 0x04 : FMC04 CE Control Register */ ++#define FMC_CTRL_CE1_4BYTE_MODE (0x1 << 1) ++#define FMC_CTRL_CE0_4BYTE_MODE (0x1) ++ ++/* FMC_SPI_DMA_STS : 0x08 : FMC08 Interrupt Control and Status Register */ ++#define FMC_STS_DMA_READY 0x0800 ++#define FMC_STS_DMA_CLEAR 0x0800 ++ ++/* FMC_CE0_CTRL for SPI 0x10, 0x14, 0x18, 0x1c, 0x20 */ ++#define SPI_IO_MODE_MASK (3 << 28) ++#define SPI_SINGLE_BIT (0 << 28) ++#define SPI_DUAL_MODE (0x2 << 28) ++#define SPI_DUAL_IO_MODE (0x3 << 28) ++#define SPI_QUAD_MODE (0x4 << 28) ++#define SPI_QUAD_IO_MODE (0x5 << 28) ++ ++#define SPI_CE_WIDTH(x) (x << 24) ++#define SPI_CMD_DATA_MASK (0xff << 16) ++#define SPI_CMD_DATA(x) (x << 16) ++#define SPI_DUMMY_CMD (1 << 15) ++#define SPI_DUMMY_HIGH (1 << 14) ++//#define SPI_CLK_DIV (1 << 13) ?? TODO ask.... ++//#define SPI_ADDR_CYCLE (1 << 13) ?? TODO ask.... ++#define SPI_CMD_MERGE_DIS (1 << 12) ++#define SPI_CLK_DIV(x) (x << 8) ++#define SPI_CLK_DIV_MASK (0xf << 8) ++ ++#define SPI_DUMMY_LOW_MASK (0x3 << 6) ++#define SPI_DUMMY_LOW(x) ((x) << 6) ++#define SPI_LSB_FIRST_CTRL (1 << 5) ++#define SPI_CPOL_1 (1 << 4) ++#define SPI_DUAL_DATA (1 << 3) ++#define SPI_CE_INACTIVE (1 << 2) ++#define SPI_CMD_MODE_MASK (0x3) ++#define SPI_CMD_NORMAL_READ_MODE 0 ++#define SPI_CMD_READ_CMD_MODE 1 ++#define SPI_CMD_WRITE_CMD_MODE 2 ++#define SPI_CMD_USER_MODE 3 ++ ++/* AST_SPI_DMA_CTRL 0x80 */ ++#define FMC_DMA_ENABLE (0x1) ++ ++/******************************************************************************/ ++struct fmc_spi_host { ++ void __iomem *base; ++ void __iomem *ctrl_reg; ++ u32 buff[5]; ++ struct spi_master *master; ++ struct spi_device *spi_dev; ++ struct device *dev; ++ u32 ahb_clk; ++ spinlock_t lock; ++}; ++ ++static u32 ast_spi_calculate_divisor(struct fmc_spi_host *host, ++ u32 max_speed_hz) ++{ ++ // [0] ->15 : HCLK , HCLK/16 ++ u8 SPI_DIV[16] = { ++ 16, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 0 ++ }; ++ u32 i, spi_cdvr = 0; ++ ++ for (i = 1; i < 17; i++) { ++ if (max_speed_hz >= (host->ahb_clk / i)) { ++ spi_cdvr = SPI_DIV[i - 1]; ++ break; ++ } ++ } ++ ++ // printk("hclk is %d, divisor is %d, target :%d , cal speed %d\n", host->ahb_clk, spi_cdvr, spi->max_speed_hz, hclk/i); ++ return spi_cdvr; ++} ++ ++/* the spi->mode bits understood by this driver: */ ++#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH) ++ ++static int fmc_spi_setup(struct spi_device *spi) ++{ ++ struct fmc_spi_host *host = ++ (struct fmc_spi_host *)spi_master_get_devdata(spi->master); ++ unsigned int bits = spi->bits_per_word; ++ u32 fmc_config = 0; ++ u32 spi_ctrl = 0; ++ u32 divisor; ++ ++ // dev_dbg(host->dev, "fmc_spi_setup() cs: %d, spi->mode %d \n", spi->chip_select, spi->mode); ++ // printk("fmc_spi_setup() cs: %d, spi->mode %d spi->max_speed_hz %d , spi->bits_per_word %d \n", spi->chip_select, spi->mode, spi->max_speed_hz, spi->bits_per_word); ++ ++ switch (spi->chip_select) { ++ case 0: ++ fmc_config |= FMC_CONF_CE0_WEN | FMC_CONF_CE0_SPI; ++ host->ctrl_reg = host->base + FMC_SPI_CE0_CTRL; ++ break; ++ case 1: ++ fmc_config |= FMC_CONF_CE1_WEN | FMC_CONF_CE1_SPI; ++ host->ctrl_reg = host->base + FMC_SPI_CE0_CTRL; ++ break; ++ default: ++ dev_dbg(&spi->dev, ++ "setup: invalid chipselect %u (%u defined)\n", ++ spi->chip_select, spi->master->num_chipselect); ++ return -EINVAL; ++ break; ++ } ++ writel(fmc_config, host->base); ++ ++ if (bits == 0) ++ bits = 8; ++ ++ if (bits < 8 || bits > 16) { ++ dev_dbg(&spi->dev, ++ "setup: invalid bits_per_word %u (8 to 16)\n", bits); ++ return -EINVAL; ++ } ++ ++ if (spi->mode & ~MODEBITS) { ++ dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", ++ spi->mode & ~MODEBITS); ++ return -EINVAL; ++ } ++ ++ /* see notes above re chipselect */ ++ if ((spi->chip_select == 0) && (spi->mode & SPI_CS_HIGH)) { ++ dev_dbg(&spi->dev, "setup: can't be active-high\n"); ++ return -EINVAL; ++ } ++ ++ /* ++ * Pre-new_1 chips start out at half the peripheral ++ * bus speed. ++ */ ++ ++ if (spi->max_speed_hz) { ++ /* Set the SPI slaves select and characteristic control register */ ++ divisor = ast_spi_calculate_divisor(host, spi->max_speed_hz); ++ } else { ++ /* speed zero means "as slow as possible" */ ++ divisor = 15; ++ } ++ ++ spi_ctrl &= ~SPI_CLK_DIV_MASK; ++ // printk("set div %x \n",divisor); ++ //TODO MASK first ++ spi_ctrl |= SPI_CLK_DIV(divisor); ++ ++ /* only support mode 0 (CPOL=0, CPHA=0) and cannot support mode 1 ~ mode 3 */ ++ ++#if 0 ++ if (SPI_CPHA & spi->mode) ++ cpha = SPI_CPHA_1; ++ else ++ cpha = SPI_CPHA_0; ++#endif ++ ++ // if (SPI_CPOL & spi->mode) ++ // spi_ctrl |= SPI_CPOL_1; ++ // else ++ // spi_ctrl &= ~SPI_CPOL_1; ++ ++ //ISSUE : ast spi ctrl couldn't use mode 3, so fix mode 0 ++ spi_ctrl &= ~SPI_CPOL_1; ++ ++ if (SPI_LSB_FIRST & spi->mode) ++ spi_ctrl |= SPI_LSB_FIRST_CTRL; ++ else ++ spi_ctrl &= ~SPI_LSB_FIRST_CTRL; ++ ++ /* Configure SPI controller */ ++ writel(spi_ctrl, host->ctrl_reg); ++ ++ // printk("ctrl %x, ", spi_ctrl); ++ return 0; ++} ++ ++static int fmc_spi_transfer(struct spi_device *spi, struct spi_message *msg) ++{ ++ struct fmc_spi_host *host = ++ (struct fmc_spi_host *)spi_master_get_devdata(spi->master); ++ struct spi_transfer *xfer; ++ const u8 *tx_buf; ++ u8 *rx_buf; ++ unsigned long flags; ++ ++ int i = 0, j = 0; ++ ++ // dev_dbg(host->dev, "xfer %s \n", dev_name(&spi->dev)); ++ // printk("xfer spi->chip_select %d \n", spi->chip_select); ++ ++ host->spi_dev = spi; ++ spin_lock_irqsave(&host->lock, flags); ++ ++ writel(readl(host->ctrl_reg) | SPI_CMD_USER_MODE, host->ctrl_reg); ++ msg->actual_length = 0; ++ msg->status = 0; ++ ++ list_for_each_entry (xfer, &msg->transfers, transfer_list) { ++ dev_dbg(host->dev, ++ "xfer[%d] %p: width %d, len %u, tx %p/%08x, rx %p/%08x\n", ++ j, xfer, xfer->bits_per_word, xfer->len, xfer->tx_buf, ++ xfer->tx_dma, xfer->rx_buf, xfer->rx_dma); ++ ++ tx_buf = xfer->tx_buf; ++ rx_buf = xfer->rx_buf; ++ ++ if (tx_buf != 0) { ++#if 0 ++ printk("tx : "); ++ if(xfer->len > 10) { ++ for(i=0;i<10;i++) ++ printk("%x ",tx_buf[i]); ++ } else { ++ for(i=0;ilen;i++) ++ printk("%x ",tx_buf[i]); ++ } ++ printk("\n"); ++#endif ++ for (i = 0; i < xfer->len; i++) { ++ writeb(tx_buf[i], ++ (void *)host->buff ++ [host->spi_dev->chip_select]); ++ } ++ } ++ //Issue need clarify ++ udelay(1); ++ if (rx_buf != 0) { ++ for (i = 0; i < xfer->len; i++) { ++ rx_buf[i] = readb( ++ (void *)host->buff ++ [host->spi_dev->chip_select]); ++ } ++#if 0 ++ printk("rx : "); ++ if(xfer->len > 10) { ++ for(i=0;i<10;i++) ++ printk(" %x",rx_buf[i]); ++ } else { ++ for(i=0;ilen;i++) ++ printk(" %x",rx_buf[i]); ++ } ++ printk("\n"); ++#endif ++ } ++ dev_dbg(host->dev, "old msg->actual_length %d , +len %d \n", ++ msg->actual_length, xfer->len); ++ msg->actual_length += xfer->len; ++ dev_dbg(host->dev, "new msg->actual_length %d \n", ++ msg->actual_length); ++ // j++; ++ } ++ ++ // writel( SPI_CE_INACTIVE | readl(host->spi_data->ctrl_reg),host->spi_data->ctrl_reg); ++ writel(readl(host->ctrl_reg) & ~SPI_CMD_USER_MODE, host->ctrl_reg); ++ msg->status = 0; ++ ++ msg->complete(msg->context); ++ ++ // spin_unlock(&host->lock); ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ return 0; ++} ++ ++static void fmc_spi_cleanup(struct spi_device *spi) ++{ ++ struct fmc_spi_host *host = spi_master_get_devdata(spi->master); ++ unsigned long flags; ++ dev_dbg(host->dev, "fmc_spi_cleanup() \n"); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ // if (host->stay == spi) { ++ // host->stay = NULL; ++ // cs_deactivate(host, spi); ++ // } ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++#if 0 ++static int fmc_spi_flash_read(struct spi_device *spi, ++ struct spi_flash_read_message *msg) ++{ ++// struct fmc_spi_host *host = spi_master_get_devdata(spi->master); ++ int ret = 0; ++ ++// printk("read msg->from %x, msg->len %x , msg->buf %x , msg->addr_width %d , msg->dummy_bytes %x , msg->read_opcode %x \n", msg->from, msg->len, msg->buf, msg->addr_width, msg->dummy_bytes, msg->read_opcode); ++ ++// memcpy_fromio(msg->buf, b53spi->mmio_base + msg->from, msg->len); ++ msg->retlen = msg->len; ++ ++ return ret; ++} ++#endif ++ ++static int fmc_spi_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ struct fmc_spi_host *host; ++ struct spi_master *master; ++ struct clk *clk; ++ int cs_num = 0; ++ int err = 0; ++ ++ dev_dbg(&pdev->dev, "fmc_spi_probe() \n"); ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(struct fmc_spi_host)); ++ if (NULL == master) { ++ dev_err(&pdev->dev, "No memory for spi_master\n"); ++ err = -ENOMEM; ++ goto err_nomem; ++ } ++ ++ /* the spi->mode bits understood by this driver: */ ++ master->mode_bits = ++ SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_RX_DUAL | SPI_TX_DUAL; ++ master->bits_per_word_mask = SPI_BPW_MASK(8); ++ ++ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_RX_DUAL; ++ // master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); ++ master->dev.of_node = pdev->dev.of_node; ++ master->bus_num = pdev->id; ++ // master->num_chipselect = master->dev.of_node ? 0 : 4; ++ platform_set_drvdata(pdev, master); ++ ++ host = spi_master_get_devdata(master); ++ memset(host, 0, sizeof(struct fmc_spi_host)); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM 0\n"); ++ err = -ENXIO; ++ goto err_no_io_res; ++ } ++ ++ host->base = devm_ioremap_resource(&pdev->dev, res); ++ if (!host->base) { ++ dev_err(&pdev->dev, "cannot remap register\n"); ++ err = -EIO; ++ goto err_no_io_res; ++ } ++ ++ clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(clk)) { ++ dev_err(&pdev->dev, "no clock defined\n"); ++ return -ENODEV; ++ } ++ host->ahb_clk = clk_get_rate(clk); ++ ++ dev_dbg(&pdev->dev, "remap phy %x, virt %x \n", (u32)res->start, ++ (u32)host->base); ++ ++ host->master = spi_master_get(master); ++ ++ if (of_property_read_u16(pdev->dev.of_node, "number_of_chip_select", ++ &host->master->num_chipselect)) ++ goto err_register; ++ ++ for (cs_num = 0; cs_num < host->master->num_chipselect; cs_num++) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, cs_num + 1); ++ if (!res) { ++ dev_err(&pdev->dev, "cannot get IORESOURCE_IO 0\n"); ++ return -ENXIO; ++ } ++ ++ host->buff[cs_num] = ++ (u32)devm_ioremap_resource(&pdev->dev, res); ++ if (!host->buff[cs_num]) { ++ dev_err(&pdev->dev, "cannot remap buffer \n"); ++ err = -EIO; ++ goto err_no_io_res; ++ } ++ ++ dev_dbg(&pdev->dev, "remap io phy %x, virt %x \n", ++ (u32)res->start, (u32)host->buff[cs_num]); ++ } ++ ++ host->master->bus_num = pdev->id; ++ host->dev = &pdev->dev; ++ ++ /* Setup the state for bitbang driver */ ++ host->master->setup = fmc_spi_setup; ++ host->master->transfer = fmc_spi_transfer; ++ host->master->cleanup = fmc_spi_cleanup; ++ // host->master->spi_flash_read = fmc_spi_flash_read; ++ ++ platform_set_drvdata(pdev, host); ++ ++ /* Register our spi controller */ ++ err = devm_spi_register_master(&pdev->dev, host->master); ++ if (err) { ++ dev_err(&pdev->dev, "failed to register SPI master\n"); ++ goto err_register; ++ } ++ ++ dev_dbg(&pdev->dev, "fmc_spi : driver load \n"); ++ ++ return 0; ++ ++err_register: ++ spi_master_put(host->master); ++ iounmap(host->base); ++ for (cs_num = 0; cs_num < host->master->num_chipselect; cs_num++) { ++ iounmap((void *)host->buff[cs_num]); ++ } ++ ++err_no_io_res: ++ kfree(master); ++ kfree(host); ++ ++err_nomem: ++ return err; ++} ++ ++static int fmc_spi_remove(struct platform_device *pdev) ++{ ++ struct resource *res0; ++ struct fmc_spi_host *host = platform_get_drvdata(pdev); ++ ++ dev_dbg(host->dev, "fmc_spi_remove()\n"); ++ ++ if (!host) ++ return -1; ++ ++ res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ release_mem_region(res0->start, res0->end - res0->start + 1); ++ iounmap(host->base); ++ iounmap(host->buff); ++ ++ platform_set_drvdata(pdev, NULL); ++ spi_unregister_master(host->master); ++ spi_master_put(host->master); ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int fmc_spi_suspend(struct platform_device *pdev, pm_message_t msg) ++{ ++ return 0; ++} ++ ++static int fmc_spi_resume(struct platform_device *pdev) ++{ ++ return 0; ++} ++#else ++#define fmc_spi_suspend NULL ++#define fmc_spi_resume NULL ++#endif ++ ++static const struct of_device_id fmc_spi_of_match[] = { ++ { .compatible = "aspeed,fmc-spi" }, ++ {}, ++}; ++ ++static struct platform_driver fmc_spi_driver = { ++ .probe = fmc_spi_probe, ++ .remove = fmc_spi_remove, ++#ifdef CONFIG_PM ++ .suspend = fmc_spi_suspend, ++ .resume = fmc_spi_resume, ++#endif ++ .driver = { ++ .name = KBUILD_MODNAME, ++ .of_match_table = fmc_spi_of_match, ++ }, ++}; ++ ++module_platform_driver(fmc_spi_driver); ++ ++MODULE_DESCRIPTION("FMC SPI Driver"); ++MODULE_AUTHOR("Ryan Chen"); ++MODULE_LICENSE("GPL"); +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0002-Enable-pass-through-on-GPIOE1-and-GPIOE3-free.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0002-Enable-pass-through-on-GPIOE1-and-GPIOE3-free.patch index ecee21f1c..58d81db75 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0002-Enable-pass-through-on-GPIOE1-and-GPIOE3-free.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0002-Enable-pass-through-on-GPIOE1-and-GPIOE3-free.patch @@ -15,19 +15,78 @@ enabled again. Signed-off-by: Jason M. Bills --- drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c | 1 + - drivers/pinctrl/aspeed/pinctrl-aspeed.c | 60 ++++++++++++++++++++++++++++++ + drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 1 + + drivers/pinctrl/aspeed/pinctrl-aspeed.c | 60 ++++++++++++++++++++++ drivers/pinctrl/aspeed/pinctrl-aspeed.h | 3 ++ - 3 files changed, 64 insertions(+) + 4 files changed, 65 insertions(+) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c -index d8a804b9f958..5e7f53fab76e 100644 +index 0cab4c2576e2..a8d64184ace1 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c -@@ -2805,6 +2805,7 @@ static const struct pinmux_ops aspeed_g5_pinmux_ops = { +@@ -2780,6 +2780,22 @@ static int aspeed_g5_sig_expr_set(struct aspeed_pinmux_data *ctx, + return 0; + } + ++#define GPIOE1 33 ++#define GPIOE3 35 ++static void aspeed_g5_gpio_disable_free(struct pinctrl_dev *pctldev, ++ struct pinctrl_gpio_range *range, ++ unsigned int offset) ++{ ++ /* ++ * If we're freeing GPIOE1 (33) or GPIOE3 (35) then re-enable the ++ * pass-through mux setting; otherwise, do nothing. ++ */ ++ if (offset != GPIOE1 && offset != GPIOE3) ++ return; ++ ++ aspeed_gpio_disable_free(pctldev, range, offset); ++} ++ + static const struct aspeed_pin_config_map aspeed_g5_pin_config_map[] = { + { PIN_CONFIG_BIAS_PULL_DOWN, 0, 1, BIT_MASK(0)}, + { PIN_CONFIG_BIAS_PULL_DOWN, -1, 0, BIT_MASK(0)}, +@@ -2815,6 +2837,7 @@ static const struct pinmux_ops aspeed_g5_pinmux_ops = { .get_function_groups = aspeed_pinmux_get_fn_groups, .set_mux = aspeed_pinmux_set_mux, .gpio_request_enable = aspeed_gpio_request_enable, -+ .gpio_disable_free = aspeed_gpio_disable_free, ++ .gpio_disable_free = aspeed_g5_gpio_disable_free, + .strict = true, + }; + +diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +index eb0c11a9fbf2..cae6fdd83c80 100644 +--- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c ++++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +@@ -2655,6 +2655,22 @@ static int aspeed_g6_sig_expr_set(struct aspeed_pinmux_data *ctx, + return 0; + } + ++#define GPIOP1 121 ++#define GPIOP3 123 ++static void aspeed_g6_gpio_disable_free(struct pinctrl_dev *pctldev, ++ struct pinctrl_gpio_range *range, ++ unsigned int offset) ++{ ++ /* ++ * If we're freeing GPIOP1 (121) or GPIOP3 (123) then re-enable the ++ * pass-through mux setting; otherwise, do nothing. ++ */ ++ if (offset != GPIOP1 && offset != GPIOP3) ++ return; ++ ++ aspeed_gpio_disable_free(pctldev, range, offset); ++} ++ + static const struct aspeed_pin_config_map aspeed_g6_pin_config_map[] = { + { PIN_CONFIG_BIAS_PULL_DOWN, 0, 1, BIT_MASK(0)}, + { PIN_CONFIG_BIAS_PULL_DOWN, -1, 0, BIT_MASK(0)}, +@@ -2695,6 +2717,7 @@ static const struct pinmux_ops aspeed_g6_pinmux_ops = { + .get_function_groups = aspeed_pinmux_get_fn_groups, + .set_mux = aspeed_pinmux_set_mux, + .gpio_request_enable = aspeed_gpio_request_enable, ++ .gpio_disable_free = aspeed_g6_gpio_disable_free, .strict = true, }; @@ -35,33 +94,26 @@ diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pi index 54933665b5f8..aa7d56e99824 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c -@@ -356,6 +356,66 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, - return aspeed_sig_expr_enable(&pdata->pinmux, expr); +@@ -375,6 +375,59 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, + return 0; } +void aspeed_gpio_disable_free(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ -+ const struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); ++ struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + const struct aspeed_pin_desc *pdesc = pdata->pins[offset].drv_data; + const struct aspeed_sig_expr ***prios, **funcs, *expr; + int ret; + -+ /* -+ * If we're freeing GPIOE1 (33) or GPIOE3 (35) then re-enable the -+ * pass-through mux setting; otherwise, do nothing. -+ */ -+ if (offset != 33 && offset != 35) ++ if (!pdesc) + return; + + dev_dbg(pctldev->dev, + "Freeing pass-through pin %s (%d). Re-enabling pass-through.\n", + pdesc->name, offset); + -+ if (!pdesc) -+ return; -+ + prios = pdesc->prios; + + if (!prios) @@ -106,7 +158,7 @@ diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.h b/drivers/pinctrl/aspeed/pi index a5d83986f32e..c1104341e202 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.h +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.h -@@ -67,6 +67,9 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, +@@ -101,6 +101,9 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned int offset); diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0003-Enable-GPIOE0-and-GPIOE2-pass-through-by-default.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0003-Enable-GPIOE0-and-GPIOE2-pass-through-by-default.patch index 263b64822..1ee1c68de 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0003-Enable-GPIOE0-and-GPIOE2-pass-through-by-default.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0003-Enable-GPIOE0-and-GPIOE2-pass-through-by-default.patch @@ -54,8 +54,8 @@ index 09e53c5..6165b44 100644 /* + * Select the pass-through pinctrl config to enable the pass-through -+ * mux for GPIOs E0 and E2. Then call pinctrl_put() to release claim -+ * of the GPIO pins, so they can be requested at runtime. ++ * mux for GPIOs marked as pass-through. Then call pinctrl_put() to ++ * release claim of the GPIO pins, so they can be requested at runtime. + */ + pinctrl = pinctrl_get_select(&pdev->dev, "pass-through"); + if (!IS_ERR(pinctrl)) diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0006-Allow-monitoring-of-power-control-input-GPIOs.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0006-Allow-monitoring-of-power-control-input-GPIOs.patch index c84746359..0b0e430c6 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0006-Allow-monitoring-of-power-control-input-GPIOs.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0006-Allow-monitoring-of-power-control-input-GPIOs.patch @@ -75,6 +75,48 @@ index 5e7f53fab76e..b08b5325edb1 100644 SIG_EXPR_LIST_DECL_DUAL(P21, SIOONCTRL, SIOONCTRL, ACPI); SIG_EXPR_LIST_DECL_SINGLE(P21, DASHP21, DASHP21, SIG_DESC_SET(SCU94, 11)); PIN_DECL_2(P21, GPIOY3, SIOONCTRL, DASHP21); +diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +index cae6fdd83c80..6ff185d63ab7 100644 +--- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c ++++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +@@ -762,7 +762,7 @@ SSSF_PIN_DECL(AC23, GPIOO7, PWM7, SIG_DESC_SET(SCU41C, 23)); + + #define AB22 120 + SIG_EXPR_LIST_DECL_SEMG(AB22, PWM8, PWM8G1, PWM8, SIG_DESC_SET(SCU41C, 24)); +-SIG_EXPR_LIST_DECL_SESG(AB22, THRUIN0, THRU0, SIG_DESC_SET(SCU4BC, 24)); ++SIG_EXPR_LIST_DECL_SESG(AB22, THRUIN0, THRU0); + PIN_DECL_2(AB22, GPIOP0, PWM8, THRUIN0); + GROUP_DECL(PWM8G1, AB22); + FUNC_DECL_2(PWM8, PWM8G0, PWM8G1); +@@ -779,7 +779,7 @@ FUNC_DECL_2(PWM9, PWM9G0, PWM9G1); + + #define AA23 122 + SIG_EXPR_LIST_DECL_SEMG(AA23, PWM10, PWM10G1, PWM10, SIG_DESC_SET(SCU41C, 26)); +-SIG_EXPR_LIST_DECL_SESG(AA23, THRUIN1, THRU1, SIG_DESC_SET(SCU4BC, 26)); ++SIG_EXPR_LIST_DECL_SESG(AA23, THRUIN1, THRU1); + PIN_DECL_2(AA23, GPIOP2, PWM10, THRUIN1); + GROUP_DECL(PWM10G1, AA23); + FUNC_DECL_2(PWM10, PWM10G0, PWM10G1); +@@ -1070,16 +1070,16 @@ FUNC_GROUP_DECL(GPIU7, AC17); + FUNC_GROUP_DECL(ADC15, AC17); + + #define AB15 168 +-SSSF_PIN_DECL(AB15, GPIOV0, SIOS3, SIG_DESC_SET(SCU434, 8)); ++SSSF_PIN_DECL(AB15, GPIOV0, SIOS3); + + #define AF14 169 +-SSSF_PIN_DECL(AF14, GPIOV1, SIOS5, SIG_DESC_SET(SCU434, 9)); ++SSSF_PIN_DECL(AF14, GPIOV1, SIOS5); + + #define AD14 170 + SSSF_PIN_DECL(AD14, GPIOV2, SIOPWREQ, SIG_DESC_SET(SCU434, 10)); + + #define AC15 171 +-SSSF_PIN_DECL(AC15, GPIOV3, SIOONCTRL, SIG_DESC_SET(SCU434, 11)); ++SSSF_PIN_DECL(AC15, GPIOV3, SIOONCTRL); + + #define AE15 172 + SSSF_PIN_DECL(AE15, GPIOV4, SIOPWRGD, SIG_DESC_SET(SCU434, 12)); -- 2.7.4 diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0015-New-flash-map-for-intel.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0015-New-flash-map-for-intel.patch index 695491d28..b9de9f5a9 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0015-New-flash-map-for-intel.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0015-New-flash-map-for-intel.patch @@ -1,7 +1,7 @@ From f57d473a30f208754457bdb63512c307f7499ac8 Mon Sep 17 00:00:00 2001 From: Vernon Mauery Date: Mon, 4 Jun 2018 13:45:42 -0700 -Subject: [PATCH] New flash map for Intel +Subject: [PATCH] New flash map for intel Signed-off-by: Vernon Mauery Signed-off-by: Vikram Bodireddy diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0016-Add-ASPEED-SGPIO-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0016-Add-ASPEED-SGPIO-driver.patch index 07bdf60af..2f03c9e5a 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0016-Add-ASPEED-SGPIO-driver.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0016-Add-ASPEED-SGPIO-driver.patch @@ -1,7 +1,7 @@ From ab104c6067683a3a251e2814991474243b7e1cb8 Mon Sep 17 00:00:00 2001 From: "Feist, James" Date: Tue, 4 Jun 2019 14:00:39 -0700 -Subject: [PATCH] gpio: aspeed: add ASPEED SGPIO driver +Subject: [PATCH] Add ASPEED SGPIO driver Add SGPIO driver support for Aspeed SoCs. diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0017-SGPIO-DT-and-pinctrl-fixup.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0017-SGPIO-DT-and-pinctrl-fixup.patch index 6bfcb43c4..b4f46c2c8 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0017-SGPIO-DT-and-pinctrl-fixup.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0017-SGPIO-DT-and-pinctrl-fixup.patch @@ -105,6 +105,32 @@ index 271f3c96456a..128e0b5bbae2 100644 }; rtc: rtc@1e781000 { +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index 1aab48fbf49e..567f268a3032 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -356,6 +356,21 @@ + #interrupt-cells = <2>; + }; + ++ sgpio: sgpio@1e780500 { ++ #gpio-cells = <2>; ++ gpio-controller; ++ compatible = "aspeed,ast2500-sgpio"; ++ reg = <0x1e780500 0x0100>; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ interrupt-controller; ++ bus-frequency = <1000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_sgpm1_default>; ++ clocks = <&syscon ASPEED_CLK_APB1>; ++ status = "disabled"; ++ }; ++ + rtc: rtc@1e781000 { + compatible = "aspeed,ast2600-rtc"; + reg = <0x1e781000 0x18>; diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c index 95ea593fa29d..70284c5f9ad9 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0018-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0018-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch index 77e413125..d1da4c599 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0018-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0018-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch @@ -5212,7 +5212,7 @@ index a6dae71..253fb42 100644 -#define WRPCICFGLOCAL_PECI_CMD 0xe5 - -#define PECI_BUFFER_SIZE 32 -+#define PECI_DEV_RETRY_TIME_MS 250 ++#define PECI_DEV_RETRY_TIME_MS 700 +#define PECI_DEV_RETRY_INTERVAL_USEC 10000 +#define PECI_DEV_RETRY_BIT 0x01 diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0019-Add-I2C-IPMB-support.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0019-Add-I2C-IPMB-support.patch index 675125322..128b11ecf 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0019-Add-I2C-IPMB-support.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0019-Add-I2C-IPMB-support.patch @@ -1,7 +1,7 @@ From f588865f8180a6370ac639bdfc186ffc5b926246 Mon Sep 17 00:00:00 2001 From: Haiyue Wang Date: Tue, 13 Feb 2018 14:28:12 +0800 -Subject: [PATCH] i2c: slave-mqueue: add mqueue driver to receive ipmi message +Subject: [PATCH] Add I2C IPMB support Some protocols over I2C are designed for bi-directional transferring messages by using I2C Master Write protocol. Like the MCTP (Management 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 07283f54d..a82fefba0 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,8 +1,7 @@ From 6e55e28db5eed85b7717aa4fc92c064f11429f6d Mon Sep 17 00:00:00 2001 From: Haiyue Wang Date: Sat, 24 Feb 2018 11:12:32 +0800 -Subject: [PATCH] eSPI: add ASPEED AST2500 eSPI driver to boot a host with PCH - runs on eSPI +Subject: [PATCH] Add AST2500 eSPI driver When PCH works under eSPI mode, the PMC (Power Management Controller) in PCH is waiting for SUS_ACK from BMC after it alerts SUS_WARN. It is in @@ -22,10 +21,12 @@ Also, it provides monitoring interface of PLTRST_N signal through Signed-off-by: Haiyue Wang Signed-off-by: Jae Hyun Yoo Signed-off-by: James Feist +Signed-off-by: Vernon Mauery --- .../devicetree/bindings/misc/aspeed,espi-slave.txt | 19 + Documentation/misc-devices/espi-slave.rst | 118 ++++++ arch/arm/boot/dts/aspeed-g5.dtsi | 4 + + arch/arm/boot/dts/aspeed-g6.dtsi | 12 + drivers/misc/Kconfig | 8 + drivers/misc/Makefile | 1 + drivers/misc/aspeed-espi-slave.c | 420 +++++++++++++++++++++ @@ -39,12 +40,13 @@ new file mode 100644 index 000000000000..8660e2ffbb89 --- /dev/null +++ b/Documentation/devicetree/bindings/misc/aspeed,espi-slave.txt -@@ -0,0 +1,19 @@ +@@ -0,0 +1,20 @@ +ASPEED eSPI Slave Controller + +Required properties: + - compatible: must be one of: + - "aspeed,ast2500-espi-slave" ++ - "aspeed,ast2600-espi-slave" + + - reg: physical base address of the controller and length of memory mapped + region @@ -205,6 +207,36 @@ index 88f75736fe48..26671cc4dbd5 100644 }; lpc: lpc@1e789000 { +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index 567f268a3032..48de17a24c74 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -3,6 +3,7 @@ + + #include + #include ++#include + + / { + model = "Aspeed BMC"; +@@ -512,6 +513,17 @@ + status = "disabled"; + }; + ++ espi: espi@1e6ee000 { ++ compatible = "aspeed,ast2600-espi-slave"; ++ reg = <0x1e6ee000 0x200>; ++ interrupts-extended = <&gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>, ++ <&gpio0 ASPEED_GPIO(W, 7) IRQ_TYPE_EDGE_FALLING>; ++ status = "disabled"; ++ clocks = <&syscon ASPEED_CLK_GATE_ESPICLK>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_espi_default>; ++ }; ++ + i2c: bus@1e78a000 { + compatible = "simple-bus"; + #address-cells = <1>; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index d681b7201f8c..50814caba1d3 100644 --- a/drivers/misc/Kconfig @@ -241,7 +273,7 @@ new file mode 100644 index 000000000000..b0fc01692d3a --- /dev/null +++ b/drivers/misc/aspeed-espi-slave.c -@@ -0,0 +1,420 @@ +@@ -0,0 +1,421 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2015-2019, Intel Corporation. + @@ -644,6 +676,7 @@ index 000000000000..b0fc01692d3a + +static const struct of_device_id of_espi_match_table[] = { + { .compatible = "aspeed,ast2500-espi-slave" }, ++ { .compatible = "aspeed,ast2600-espi-slave" }, + { } +}; +MODULE_DEVICE_TABLE(of, of_espi_match_table); diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch index 4dc14d3b1..223c15fc6 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch @@ -461,7 +461,7 @@ index 2a6be04..43a86a0 100644 + msg->tx_buf[6] = (u8)umsg->param1; + msg->tx_buf[7] = (u8)(umsg->param1 >> 8); + msg->tx_buf[8] = (u8)umsg->param2; -+ msg->tx_buf[8] = (u8)(umsg->param2 >> 8); ++ msg->tx_buf[9] = (u8)(umsg->param2 >> 8); + + ret = peci_xfer_with_retries(adapter, msg, false); + if (!ret) diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0028-Add-AST2500-JTAG-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0028-Add-AST2500-JTAG-driver.patch index 28bc8d36c..45dec5b20 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0028-Add-AST2500-JTAG-driver.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0028-Add-AST2500-JTAG-driver.patch @@ -1,9 +1,9 @@ From a4413fe3ba94906243b632e0b9e0e9a91620dd22 Mon Sep 17 00:00:00 2001 From: "Corona, Ernesto" Date: Fri, 1 Mar 2019 11:46:09 -0700 -Subject: [PATCH] Update AST2500d JTAG driver. Step 1 +Subject: [PATCH] Add AST2500 JTAG driver -Update AST2500d JTAG driver. Remove Legacy driver but keep headers. +Update AST2500 JTAG driver. Remove Legacy driver but keep headers. Signed-off-by: Corona, Ernesto --- diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0032-misc-aspeed-Add-Aspeed-UART-routing-control-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0032-misc-aspeed-Add-Aspeed-UART-routing-control-driver.patch index f1e3612e8..f1507020a 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0032-misc-aspeed-Add-Aspeed-UART-routing-control-driver.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0032-misc-aspeed-Add-Aspeed-UART-routing-control-driver.patch @@ -13,15 +13,16 @@ the other UARTs wired up in a testable way. Signed-off-by: Oskar Senft Signed-off-by: Yong Li +Signed-off-by: Vernon Mauery --- - .../ABI/stable/sysfs-driver-aspeed-uart-routing | 14 + - Documentation/misc-devices/aspeed-uart-routing.txt | 49 +++ - arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts | 4 + - arch/arm/boot/dts/aspeed-g5.dtsi | 6 + - drivers/misc/Kconfig | 6 + - drivers/misc/Makefile | 1 + - drivers/misc/aspeed-uart-routing.c | 383 +++++++++++++++++++++ - 7 files changed, 463 insertions(+) + .../stable/sysfs-driver-aspeed-uart-routing | 14 + + .../misc-devices/aspeed-uart-routing.txt | 49 +++ + arch/arm/boot/dts/aspeed-g5.dtsi | 6 + + arch/arm/boot/dts/aspeed-g6.dtsi | 6 + + drivers/misc/Kconfig | 6 + + drivers/misc/Makefile | 1 + + drivers/misc/aspeed-uart-routing.c | 383 ++++++++++++++++++ + 7 files changed, 465 insertions(+) create mode 100644 Documentation/ABI/stable/sysfs-driver-aspeed-uart-routing create mode 100644 Documentation/misc-devices/aspeed-uart-routing.txt create mode 100644 drivers/misc/aspeed-uart-routing.c @@ -56,7 +57,7 @@ index 000000000000..afaf17cb7eda +================================= + +Supported chips: -+ASPEED AST2500 ++ASPEED AST2500/AST2600 + +Author: +Google LLC @@ -64,8 +65,8 @@ index 000000000000..afaf17cb7eda +Description +----------- + -+The Aspeed AST2500 allows to dynamically route the inputs for the built-in -+UARTS and physical serial I/O ports. ++The Aspeed AST2500/AST2600 allows to dynamically route the inputs for the ++built-in UARTS and physical serial I/O ports. + +This allows, for example, to connect the output of UART to another UART. +This can be used to enable host<->BMC communication via UARTs, e.g. to allow @@ -101,21 +102,6 @@ index 000000000000..afaf17cb7eda + >/sys/bus/platform/drivers/aspeed-uart-routing/*.uart_routing/uart1 +$ cat /sys/bus/platform/drivers/aspeed-uart-routing/*.uart_routing/uart1 +io1 io2 io3 io4 uart2 [uart3] uart4 io6 -diff --git a/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts b/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts -index 0aa2ac82cae4..403f29a74281 100644 ---- a/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts -+++ b/arch/arm/boot/dts/aspeed-bmc-intel-ast2500.dts -@@ -260,6 +260,10 @@ - status = "okay"; - }; - -+&uart_routing { -+ status = "okay"; -+}; -+ - &mac1 { - status = "okay"; - diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 26671cc4dbd5..8288002e4f02 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi @@ -133,6 +119,23 @@ index 26671cc4dbd5..8288002e4f02 100644 }; peci: bus@1e78b000 { +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index 48de17a24c74..3a6ff98df8ea 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -311,6 +311,12 @@ + compatible = "aspeed,ast2600-pinctrl"; + }; + ++ uart_routing: uart_routing@9c { ++ compatible = "aspeed,ast2500-uart-routing"; ++ reg = <0x9c 0x4>; ++ status = "disabled"; ++ }; ++ + smp-memram@180 { + compatible = "aspeed,ast2600-smpmem"; + reg = <0x180 0x40>; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 50814caba1d3..439f3b0de702 100644 --- a/drivers/misc/Kconfig diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0039-Add-Aspeed-PWM-driver-which-uses-FTTMR010-timer-IP.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0039-Add-Aspeed-PWM-driver-which-uses-FTTMR010-timer-IP.patch index 6d8ec4883..e6de3e473 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0039-Add-Aspeed-PWM-driver-which-uses-FTTMR010-timer-IP.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0039-Add-Aspeed-PWM-driver-which-uses-FTTMR010-timer-IP.patch @@ -471,7 +471,7 @@ index 000000000000..4c929a25e27c + struct pwm_chip *chip = &priv->chip; + unsigned int i; + -+ for (i = chip->variant.chan_min; i < chip->variant.chan_max; i++) { ++ for (i = priv->variant.chan_min; i < priv->variant.chan_max; i++) { + struct pwm_device *pwm = &chip->pwms[i]; + struct pwm_fttmr010_chan *chan = pwm_get_chip_data(pwm); + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0043-char-ipmi-Add-clock-control-logic-into-Aspeed-LPC-BT.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0043-char-ipmi-Add-clock-control-logic-into-Aspeed-LPC-BT.patch index 139d06df0..c59ff1e9c 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0043-char-ipmi-Add-clock-control-logic-into-Aspeed-LPC-BT.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0043-char-ipmi-Add-clock-control-logic-into-Aspeed-LPC-BT.patch @@ -15,12 +15,14 @@ individually so this patch adds clock control logic into the LPC BT driver. Signed-off-by: Jae Hyun Yoo +Signed-off-by: Vernon Mauery --- - .../bindings/ipmi/aspeed,ast2400-ibt-bmc.txt | 3 +++ - arch/arm/boot/dts/aspeed-g4.dtsi | 1 + - arch/arm/boot/dts/aspeed-g5.dtsi | 1 + - drivers/char/ipmi/bt-bmc.c | 24 +++++++++++++++++++++- - 4 files changed, 28 insertions(+), 1 deletion(-) + .../bindings/ipmi/aspeed,ast2400-ibt-bmc.txt | 3 +++ + arch/arm/boot/dts/aspeed-g4.dtsi | 1 + + arch/arm/boot/dts/aspeed-g5.dtsi | 1 + + arch/arm/boot/dts/aspeed-g6.dtsi | 1 + + drivers/char/ipmi/bt-bmc.c | 24 ++++++++++++++++++- + 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.txt b/Documentation/devicetree/bindings/ipmi/aspeed,ast2400-ibt-bmc.txt index 028268fd99ee..d13887d60f19 100644 @@ -65,6 +67,18 @@ index 653e03a0fa4c..49f792eafdd1 100644 interrupts = <8>; status = "disabled"; }; +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index 653e03a0fa4c..49f792eafdd1 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -546,6 +546,7 @@ + ibt: ibt@c0 { + compatible = "aspeed,ast2600-ibt-bmc"; + reg = <0xc0 0x18>; ++ clocks = <&syscon ASPEED_CLK_GATE_LCLK>; + interrupts = ; + status = "disabled"; + }; diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c index 40b9927c072c..a4ec9d1743d7 100644 --- a/drivers/char/ipmi/bt-bmc.c diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0044-misc-Add-clock-control-logic-into-Aspeed-LPC-SNOOP-d.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0044-misc-Add-clock-control-logic-into-Aspeed-LPC-SNOOP-d.patch index cd20e77ac..bfd65cbe3 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0044-misc-Add-clock-control-logic-into-Aspeed-LPC-SNOOP-d.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0044-misc-Add-clock-control-logic-into-Aspeed-LPC-SNOOP-d.patch @@ -15,11 +15,14 @@ individually so this patch adds clock control logic into the LPC SNOOP driver. Signed-off-by: Jae Hyun Yoo +Signed-off-by: Vernon Mauery --- arch/arm/boot/dts/aspeed-g4.dtsi | 1 + arch/arm/boot/dts/aspeed-g5.dtsi | 1 + + arch/arm/boot/dts/aspeed-g6.dtsi | 1 + drivers/soc/aspeed/aspeed-lpc-snoop.c | 30 +++++++++++++++++++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) + 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index b3b6720fb6fb..58c5148194a3 100644 @@ -45,6 +48,18 @@ index 49f792eafdd1..955789d8c736 100644 status = "disabled"; }; +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index 49f792eafdd1..955789d8c736 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -400,6 +527,7 @@ + compatible = "aspeed,ast2600-lpc-snoop"; + reg = <0x0 0x80>; + interrupts = ; ++ clocks = <&syscon ASPEED_CLK_GATE_LCLK>; + status = "disabled"; + }; + diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c index 48f7ac238861..96ea52db25be 100644 --- a/drivers/soc/aspeed/aspeed-lpc-snoop.c diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0045-char-ipmi-Add-clock-control-logic-into-Aspeed-LPC-KC.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0045-char-ipmi-Add-clock-control-logic-into-Aspeed-LPC-KC.patch index cfff0a842..f8515351b 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0045-char-ipmi-Add-clock-control-logic-into-Aspeed-LPC-KC.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0045-char-ipmi-Add-clock-control-logic-into-Aspeed-LPC-KC.patch @@ -16,12 +16,14 @@ individually so this patch adds clock control logic into the LPC KCS driver. Signed-off-by: Jae Hyun Yoo +Signed-off-by: Vernon Mauery --- .../devicetree/bindings/ipmi/aspeed-kcs-bmc.txt | 3 ++ arch/arm/boot/dts/aspeed-g4.dtsi | 35 ++++++++++++++++++++ arch/arm/boot/dts/aspeed-g5.dtsi | 6 +++- + arch/arm/boot/dts/aspeed-g6.dtsi | 4 ++ drivers/char/ipmi/kcs_bmc_aspeed.c | 37 ++++++++++++++++++---- - 4 files changed, 73 insertions(+), 8 deletions(-) + 5 files changed, 77 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt index d98a9bf45d6c..3453eb0bf8f2 100644 @@ -140,6 +142,42 @@ index 955789d8c736..19739183c1c8 100644 status = "disabled"; }; +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index 955789d8c736..19739183c1c8 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -356,18 +477,23 @@ + kcs1: kcs1@0 { + compatible = "aspeed,ast2600-kcs-bmc"; + interrupts = ; ++ clocks = <&syscon ASPEED_CLK_GATE_LCLK>; + kcs_chan = <1>; + status = "disabled"; + }; ++ + kcs2: kcs2@0 { + compatible = "aspeed,ast2600-kcs-bmc"; + interrupts = ; ++ clocks = <&syscon ASPEED_CLK_GATE_LCLK>; + kcs_chan = <2>; + status = "disabled"; + }; ++ + kcs3: kcs3@0 { + compatible = "aspeed,ast2600-kcs-bmc"; + interrupts = ; ++ clocks = <&syscon ASPEED_CLK_GATE_LCLK>; + kcs_chan = <3>; + status = "disabled"; + }; +@@ -385,6 +511,7 @@ + kcs4: kcs4@0 { + compatible = "aspeed,ast2600-kcs-bmc"; + interrupts = ; ++ clocks = <&syscon ASPEED_CLK_GATE_LCLK>; + kcs_chan = <4>; + status = "disabled"; + }; diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c index 3c955946e647..bd1912dc5a21 100644 --- a/drivers/char/ipmi/kcs_bmc_aspeed.c diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0051-Add-AST2500-JTAG-device.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0051-Add-AST2500-JTAG-device.patch index 02bb6527f..abfbcd68c 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0051-Add-AST2500-JTAG-device.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0051-Add-AST2500-JTAG-device.patch @@ -1,7 +1,7 @@ From ce35414258a8541a8b81a4a8a929bcf9cdface97 Mon Sep 17 00:00:00 2001 From: "Hunt, Bryan" Date: Mon, 6 May 2019 10:02:14 -0700 -Subject: [PATCH] Add AST2500d JTAG driver +Subject: [PATCH] Add AST2500 JTAG device Adding aspeed jtag device diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0053-Add-Aspeed-SoC-24xx-and-25xx-families-JTAG.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0053-Add-Aspeed-SoC-24xx-and-25xx-families-JTAG.patch index 94722d6c4..1ffaf7646 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0053-Add-Aspeed-SoC-24xx-and-25xx-families-JTAG.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0053-Add-Aspeed-SoC-24xx-and-25xx-families-JTAG.patch @@ -1,8 +1,7 @@ From 817a43d1b1e197e7eff43492599469bbc23bf0fd Mon Sep 17 00:00:00 2001 From: "Corona, Ernesto" Date: Mon, 3 Jun 2019 08:22:09 -0800 -Subject: [PATCH v29 2/6] Add Aspeed SoC 24xx and 25xx families JTAG master - driver +Subject: [PATCH] Add Aspeed SoC 24xx and 25xx families JTAG Driver adds support of Aspeed 2500/2400 series SOC JTAG master controller. diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0054-Documentation-jtag-Add-bindings-for-Aspeed-SoC.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0054-Documentation-jtag-Add-bindings-for-Aspeed-SoC.patch index f17bdcd68..12073da02 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0054-Documentation-jtag-Add-bindings-for-Aspeed-SoC.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0054-Documentation-jtag-Add-bindings-for-Aspeed-SoC.patch @@ -1,8 +1,7 @@ From 2a22feac440070b7feaf0a6fe7e7e555d57ca19b Mon Sep 17 00:00:00 2001 From: "Corona, Ernesto" Date: Wed, 10 Mar 2019 11:45:04 -0800 -Subject: [PATCH v29 3/6] Documentation: jtag: Add bindings for Aspeed SoC - 24xx and 25xx families JTAG master driver +Subject: [PATCH] Documentation: jtag: Add bindings for Aspeed SoC It has been tested on Mellanox system with BMC equipped with Aspeed 2520 SoC for programming CPLD devices. diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0060-i2c-aspeed-fix-master-pending-state-handling.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0060-i2c-aspeed-fix-master-pending-state-handling.patch deleted file mode 100644 index d38c089af..000000000 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0060-i2c-aspeed-fix-master-pending-state-handling.patch +++ /dev/null @@ -1,135 +0,0 @@ -From ca5e5e784ada4da11caebf6ba6852e1ff8a13bf7 Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo -Date: Tue, 11 Jun 2019 14:59:53 -0700 -Subject: [PATCH] i2c: aspeed: fix master pending state handling - -In case of master pending state, it should not trigger a master -command, otherwise data could be corrupted because this H/W shares -the same data buffer for slave and master operations. It also means -that H/W command queue handling is unreliable because of the buffer -sharing issue. To fix this issue, it clears command queue if a -master command is queued in pending state to use S/W solution -instead of H/W command queue handling. Also, it refines restarting -mechanism of the pending master command. - -Fixes: 2e57b7cebb98 ("i2c: aspeed: Add multi-master use case support") - -Signed-off-by: Jae Hyun Yoo ---- - drivers/i2c/busses/i2c-aspeed.c | 54 ++++++++++++++++++++++++++--------------- - 1 file changed, 34 insertions(+), 20 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c -index 58bdbe472721..7becfcd67142 100644 ---- a/drivers/i2c/busses/i2c-aspeed.c -+++ b/drivers/i2c/busses/i2c-aspeed.c -@@ -108,6 +108,12 @@ - #define ASPEED_I2CD_S_TX_CMD BIT(2) - #define ASPEED_I2CD_M_TX_CMD BIT(1) - #define ASPEED_I2CD_M_START_CMD BIT(0) -+#define ASPEED_I2CD_MASTER_CMDS_MASK \ -+ (ASPEED_I2CD_M_STOP_CMD | \ -+ ASPEED_I2CD_M_S_RX_CMD_LAST | \ -+ ASPEED_I2CD_M_RX_CMD | \ -+ ASPEED_I2CD_M_TX_CMD | \ -+ ASPEED_I2CD_M_START_CMD) - - /* 0x18 : I2CD Slave Device Address Register */ - #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0) -@@ -351,18 +357,19 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) - struct i2c_msg *msg = &bus->msgs[bus->msgs_index]; - u8 slave_addr = i2c_8bit_addr_from_msg(msg); - -- bus->master_state = ASPEED_I2C_MASTER_START; -- - #if IS_ENABLED(CONFIG_I2C_SLAVE) - /* - * If it's requested in the middle of a slave session, set the master - * state to 'pending' then H/W will continue handling this master - * command when the bus comes back to the idle state. - */ -- if (bus->slave_state != ASPEED_I2C_SLAVE_INACTIVE) -+ if (bus->slave_state != ASPEED_I2C_SLAVE_INACTIVE) { - bus->master_state = ASPEED_I2C_MASTER_PENDING; -+ return; -+ } - #endif /* CONFIG_I2C_SLAVE */ - -+ bus->master_state = ASPEED_I2C_MASTER_START; - bus->buf_index = 0; - - if (msg->flags & I2C_M_RD) { -@@ -437,20 +444,6 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - } - } - --#if IS_ENABLED(CONFIG_I2C_SLAVE) -- /* -- * A pending master command will be started by H/W when the bus comes -- * back to idle state after completing a slave operation so change the -- * master state from 'pending' to 'start' at here if slave is inactive. -- */ -- if (bus->master_state == ASPEED_I2C_MASTER_PENDING) { -- if (bus->slave_state != ASPEED_I2C_SLAVE_INACTIVE) -- goto out_no_complete; -- -- bus->master_state = ASPEED_I2C_MASTER_START; -- } --#endif /* CONFIG_I2C_SLAVE */ -- - /* Master is not currently active, irq was for someone else. */ - if (bus->master_state == ASPEED_I2C_MASTER_INACTIVE || - bus->master_state == ASPEED_I2C_MASTER_PENDING) -@@ -477,11 +470,15 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) - #if IS_ENABLED(CONFIG_I2C_SLAVE) - /* - * If a peer master starts a xfer immediately after it queues a -- * master command, change its state to 'pending' then H/W will -- * continue the queued master xfer just after completing the -- * slave mode session. -+ * master command, clear the queued master command and change -+ * its state to 'pending'. To simplify handling of pending -+ * cases, it uses S/W solution instead of H/W command queue -+ * handling. - */ - if (unlikely(irq_status & ASPEED_I2CD_INTR_SLAVE_MATCH)) { -+ writel(readl(bus->base + ASPEED_I2C_CMD_REG) & -+ ~ASPEED_I2CD_MASTER_CMDS_MASK, -+ bus->base + ASPEED_I2C_CMD_REG); - bus->master_state = ASPEED_I2C_MASTER_PENDING; - dev_dbg(bus->dev, - "master goes pending due to a slave start\n"); -@@ -644,6 +641,14 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) - irq_handled |= aspeed_i2c_master_irq(bus, - irq_remaining); - } -+ -+ /* -+ * Start a pending master command at here if a slave operation is -+ * completed. -+ */ -+ if (bus->master_state == ASPEED_I2C_MASTER_PENDING && -+ bus->slave_state == ASPEED_I2C_SLAVE_INACTIVE) -+ aspeed_i2c_do_start(bus); - #else - irq_handled = aspeed_i2c_master_irq(bus, irq_remaining); - #endif /* CONFIG_I2C_SLAVE */ -@@ -707,6 +712,15 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap, - ASPEED_I2CD_BUS_BUSY_STS)) - aspeed_i2c_recover_bus(bus); - -+ /* -+ * If timed out and the state is still pending, drop the pending -+ * master command. -+ */ -+ spin_lock_irqsave(&bus->lock, flags); -+ if (bus->master_state == ASPEED_I2C_MASTER_PENDING) -+ bus->master_state = ASPEED_I2C_MASTER_INACTIVE; -+ spin_unlock_irqrestore(&bus->lock, flags); -+ - return -ETIMEDOUT; - } - --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0073-Add-IO-statistics-to-USB-Mass-storage-gadget.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0073-Add-IO-statistics-to-USB-Mass-storage-gadget.patch index 41969349e..1056b3beb 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0073-Add-IO-statistics-to-USB-Mass-storage-gadget.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0073-Add-IO-statistics-to-USB-Mass-storage-gadget.patch @@ -1,7 +1,7 @@ From 5c82e0b33f2a373d5e19569635f108cfa096f53e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Ambro=C5=BCewicz?= Date: Mon, 29 Jul 2019 10:19:00 +0200 -Subject: [PATCH] Add IO stats to USB Mass Storage gadget +Subject: [PATCH] Add IO statistics to USB Mass storage gadget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0076-arm-ast2600-add-pwm_tacho-driver-from-aspeed.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0076-arm-ast2600-add-pwm_tacho-driver-from-aspeed.patch new file mode 100644 index 000000000..38a8a4a45 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0076-arm-ast2600-add-pwm_tacho-driver-from-aspeed.patch @@ -0,0 +1,1107 @@ +From d5c421c1fc4c3bfd724a92e8563bc4fac128362c Mon Sep 17 00:00:00 2001 +From: Vernon Mauery +Date: Fri, 27 Sep 2019 13:09:48 -0700 +Subject: [PATCH] arm: ast2600: add pwm_tacho driver from aspeed + +Add the pwm_tacho driver from Aspeed to get pwm working until an +upstream PWM/Tacho driver is available. This was copied from the v5.02 +BSP from Aspeed. + +Signed-off-by: Vernon Mauery +--- + arch/arm/boot/dts/aspeed-g6.dtsi | 10 + + drivers/hwmon/Kconfig | 11 + + drivers/hwmon/Makefile | 1 + + drivers/hwmon/aspeed-g6-pwm-tacho.c | 1025 +++++++++++++++++++++++++++ + 4 files changed, 1047 insertions(+) + create mode 100644 drivers/hwmon/aspeed-g6-pwm-tacho.c + +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index 03a991c97f00..b793b2f294a4 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -257,6 +257,16 @@ + #size-cells = <1>; + ranges; + ++ pwm_tacho: pwm-tacho-controller@1e610000 { ++ compatible = "aspeed,ast2600-pwm-tacho"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x1e610000 0x100>; ++ clocks = <&syscon ASPEED_CLK_AHB>; ++ resets = <&syscon ASPEED_RESET_PWM>; ++ status = "disabled"; ++ }; ++ + syscon: syscon@1e6e2000 { + compatible = "aspeed,ast2600-scu", "syscon", "simple-mfd"; + reg = <0x1e6e2000 0x1000>; +diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +index 7399c3cef30c..b5365f5602b9 100644 +--- a/drivers/hwmon/Kconfig ++++ b/drivers/hwmon/Kconfig +@@ -361,6 +361,17 @@ config SENSORS_ASPEED + This driver can also be built as a module. If so, the module + will be called aspeed_pwm_tacho. + ++config SENSORS_ASPEED_G6 ++ tristate "ASPEED AST2600 PWM and Fan tach driver" ++ depends on THERMAL || THERMAL=n ++ select REGMAP ++ help ++ This driver provides support for ASPEED AST2600 PWM ++ and Fan Tacho controllers. ++ ++ This driver can also be built as a module. If so, the module ++ will be called aspeed_g6_pwm_tacho. ++ + config SENSORS_ATXP1 + tristate "Attansic ATXP1 VID controller" + depends on I2C +diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile +index 22e0882ffc70..d21a69797a86 100644 +--- a/drivers/hwmon/Makefile ++++ b/drivers/hwmon/Makefile +@@ -50,6 +50,7 @@ obj-$(CONFIG_SENSORS_ARM_SCMI) += scmi-hwmon.o + obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o + obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o + obj-$(CONFIG_SENSORS_ASPEED) += aspeed-pwm-tacho.o ++obj-$(CONFIG_SENSORS_ASPEED_G6) += aspeed-g6-pwm-tacho.o + obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o + obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o + obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o +diff --git a/drivers/hwmon/aspeed-g6-pwm-tacho.c b/drivers/hwmon/aspeed-g6-pwm-tacho.c +new file mode 100644 +index 000000000000..d6aa5a36ca88 +--- /dev/null ++++ b/drivers/hwmon/aspeed-g6-pwm-tacho.c +@@ -0,0 +1,1025 @@ ++/* ++ * Copyright (C) ASPEED Technology Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 or later as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define ASPEED_PWM_CTRL 0x00 //PWM0 General Register ++#define ASPEED_PWM_CTRL_CH(x) ((x * 0x10) + 0x00) ++#define PWM_LOAD_AS_WDT BIT(19) //load selection as WDT ++#define PWM_DUTY_LOAD_AS_WDT_EN BIT(18) //enable PWM duty load as WDT ++#define PWM_DUTY_SYNC_DIS BIT(17) //disable PWM duty sync ++#define PWM_CLK_ENABLE BIT(16) //enable PWM clock ++#define PWM_LEVEL_OUTPUT BIT(15) //output PWM level ++#define PWM_INVERSE BIT(14) //inverse PWM pin ++#define PWM_OPEN_DRAIN_EN BIT(13) //enable open-drain ++#define PWM_PIN_EN BIT(12) //enable PWM pin ++#define PWM_CLK_DIV_H_MASK (0xf << 8) //PWM clock division H bit [3:0] ++#define PWM_CLK_DIV_L_MASK (0xff) //PWM clock division H bit [3:0] ++ ++/* ++\xregmid {11:8 }{RW}{PWM clock division H bit [3:0]}{ ++ 0: divide 1 \n ++ 1: divide 2 \n ++ 2: divide 4 \n ++ 3: divide 8 \n ++ ... \n ++ F: divide 32768} ++\xregmid {7 :0 }{RW}{PWM clock division L bit [7:0]}{ ++ 00: divide 1 \n ++ 01: divide 2 \n ++ 02: divide 3 \n ++ 03: divide 4 \n ++ ... \n ++ FF: divide 256} ++*/ ++ ++#define ASPEED_PWM_DUTY_CYCLE 0x04 //PWM0 Duty Cycle Register ++#define ASPEED_PWM_DUTY_CYCLE_CH(x) ((x * 0x10) + 0x04) ++#define PWM_LOOP_BIT_MASK (0xf << 24) //loop bit [7:0] ++#define PWM_PERIOD_BIT (24) //pwm period bit [7:0] ++#define PWM_PERIOD_BIT_MASK (0xff << 24) //pwm period bit [7:0] ++#define PWM_RISING_FALLING_AS_WDT_BIT (16) ++#define PWM_RISING_FALLING_AS_WDT_MASK (0xff << 16) //pwm rising/falling point bit [7:0] as WDT ++#define PWM_RISING_FALLING_MASK (0xffff) ++#define PWM_RISING_FALLING_BIT (8) //pwm falling point bit [7:0] ++#define PWM_RISING_RISING_BIT (0) //pwm rising point bit [7:0] ++ ++#define ASPEED_TACHO_CTRL 0x08 //TACH0 General Register ++#define ASPEED_TACHO_CTRL_CH(x) ((x * 0x10) + 0x08) ++#define TACHO_IER BIT(31) //enable tacho interrupt ++#define TACHO_INVERS_LIMIT BIT(30) //inverse tacho limit comparison ++#define TACHO_LOOPBACK BIT(29) //tacho loopback ++#define TACHO_ENABLE BIT(28) //{enable tacho} ++#define TACHO_DEBOUNCE_BIT (26) //{tacho de-bounce} ++#define TACHO_DEBOUNCE_MASK (0x3 << 26) //{tacho de-bounce} ++#define TECHIO_EDGE_MASK (0x3 << 24) //tacho edge} ++#define TECHIO_EDGE_BIT (24) //tacho edge} ++#define TACHO_CLK_DIV_T_MASK (0xf << 20) ++#define TACHO_CLK_DIV_BIT (20) ++#define TACHO_THRESHOLD_MASK (0xfffff) //tacho threshold bit ++/* ++\xregmid {23:20}{RW}{tacho clock division T bit [3:0]}{ ++ 0: divide 1 \n ++ 1: divide 4 \n ++ 2: divide 16 \n ++ 3: divide 64 \n ++ ... \n ++ B: divide 4194304 \n ++ others: reserved} ++\xregmidb{19 :0 }{RW}{tacho threshold bit [19:0]} ++*/ ++ ++#define ASPEED_TACHO_STS 0x0C //TACH0 Status Register ++#define ASPEED_TACHO_STS_CH(x) ((x * 0x10) + 0x0C) ++#define TACHO_ISR BIT(31) //interrupt status and clear ++#define PWM_OUT BIT(25) //{pwm_out} ++#define PWM_OEN BIT(24) //{pwm_oeN} ++#define TACHO_DEB_INPUT BIT(23) //tacho deB input ++#define TACHO_RAW_INPUT BIT(22) //tacho raw input} ++#define TACHO_VALUE_UPDATE BIT(21) //tacho value updated since the last read ++#define TACHO_FULL_MEASUREMENT BIT(20) //{tacho full measurement} ++#define TACHO_VALUE_MASK 0xfffff //tacho value bit [19:0]} ++ ++#define MAX_CDEV_NAME_LEN 16 ++ ++struct aspeed_pwm_channel_params { ++ int load_wdt_rising_falling_pt; ++ int load_wdt_selection; //0: rising , 1: falling ++ int load_wdt_enable; ++ int duty_sync_enable; ++ int invert_pin; ++ u8 divide_h; ++ u8 divide_l; ++ u8 period; ++ u8 rising; ++ u8 falling; ++}; ++ ++static struct aspeed_pwm_channel_params default_pwm_params[] = { ++ [0] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 1, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [1] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [2] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [3] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [4] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [5] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [6] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [7] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [8] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [9] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [10] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [11] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [12] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [13] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [14] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++ [15] = { ++ .load_wdt_rising_falling_pt = 0x10, ++ .load_wdt_selection = 0, ++ .load_wdt_enable = 0, ++ .duty_sync_enable = 0, ++ .invert_pin = 0, ++ .divide_h = 0x5, ++ .divide_l = 0x6, ++ .period = 0x13, //5% ~~ ++ .rising = 0x00, ++ .falling = 0x0a, ++ }, ++}; ++ ++/* ++ * 5:4 fan tach edge mode selection bit: ++ * 00: falling ++ * 01: rising ++ * 10: both ++ * 11: reserved. ++ */ ++ ++struct aspeed_tacho_channel_params { ++ int limited_inverse; ++ u16 threshold; ++ u8 tacho_edge; ++ u8 tacho_debounce; ++ u8 divide; ++}; ++ ++ ++static struct aspeed_tacho_channel_params default_tacho_params[] = { ++ [0] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [1] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [2] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [3] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [4] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [5] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [6] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [7] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [8] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [9] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [10] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [11] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [12] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [13] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [14] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++ [15] = { ++ .limited_inverse = 0, ++ .threshold = 0, ++ .tacho_edge = 0, ++ .tacho_debounce = 0, ++ .divide = 8, ++ }, ++}; ++ ++struct aspeed_pwm_tachometer_data { ++ struct regmap *regmap; ++ unsigned long clk_freq; ++ struct reset_control *reset; ++ bool pwm_present[16]; ++ bool fan_tach_present[16]; ++ struct aspeed_pwm_channel_params *pwm_channel; ++ struct aspeed_tacho_channel_params *tacho_channel; ++ struct aspeed_cooling_device *cdev[8]; ++ const struct attribute_group *groups[3]; ++}; ++ ++struct aspeed_cooling_device { ++ char name[16]; ++ struct aspeed_pwm_tachometer_data *priv; ++ struct thermal_cooling_device *tcdev; ++ int pwm_channel; ++ u8 *cooling_levels; ++ u8 max_state; ++ u8 cur_state; ++}; ++ ++static int regmap_aspeed_pwm_tachometer_reg_write(void *context, unsigned int reg, ++ unsigned int val) ++{ ++ void __iomem *regs = (void __iomem *)context; ++ ++ writel(val, regs + reg); ++ return 0; ++} ++ ++static int regmap_aspeed_pwm_tachometer_reg_read(void *context, unsigned int reg, ++ unsigned int *val) ++{ ++ void __iomem *regs = (void __iomem *)context; ++ ++ *val = readl(regs + reg); ++ return 0; ++} ++ ++static const struct regmap_config aspeed_pwm_tachometer_regmap_config = { ++ .reg_bits = 32, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = 0x100, ++ .reg_write = regmap_aspeed_pwm_tachometer_reg_write, ++ .reg_read = regmap_aspeed_pwm_tachometer_reg_read, ++ .fast_io = true, ++}; ++ ++static void aspeed_set_pwm_channel_enable(struct regmap *regmap, u8 pwm_channel, ++ bool enable) ++{ ++ regmap_update_bits(regmap, ASPEED_PWM_CTRL_CH(pwm_channel), (PWM_CLK_ENABLE | PWM_PIN_EN), enable ? (PWM_CLK_ENABLE | PWM_PIN_EN) : 0); ++} ++ ++static void aspeed_set_fan_tach_ch_enable(struct aspeed_pwm_tachometer_data *priv, u8 fan_tach_ch, ++ bool enable) ++{ ++ u32 i = 0, j; ++ u32 divide_val = 0; ++ u32 reg_value = 0; ++ ++ if(enable) { ++ //4 ^ n ++ //check pwm clk and to change tacho devide 25KZ ++ for(i = 0; i < 12; i++) { ++ divide_val = 1; ++ for(j = 1; j <= i; j++) ++ divide_val *= 4; ++// printk("i : %d , priv->clk_freq/divide_val %d ",i, priv->clk_freq/divide_val); ++ if((priv->clk_freq/divide_val) < 250000) ++ break; ++ } ++ i--; ++ divide_val = ((1 << i) * (1 << i)); ++// printk("tacho divide_val %d , i %x max tacho clk %d \n", divide_val, i, priv->clk_freq / divide_val); ++ priv->tacho_channel[fan_tach_ch].divide = i; ++ ++ reg_value = TACHO_ENABLE | ++ (priv->tacho_channel[fan_tach_ch].tacho_edge << TECHIO_EDGE_BIT) | ++ (priv->tacho_channel[fan_tach_ch].divide << TACHO_CLK_DIV_BIT) | ++ (priv->tacho_channel[fan_tach_ch].tacho_debounce << TACHO_DEBOUNCE_BIT); ++ ++ if(priv->tacho_channel[fan_tach_ch].limited_inverse) ++ reg_value |= TACHO_INVERS_LIMIT; ++ ++ if(priv->tacho_channel[fan_tach_ch].threshold) ++ reg_value |= (TACHO_IER | priv->tacho_channel[fan_tach_ch].threshold); ++ ++ regmap_write(priv->regmap, ASPEED_TACHO_CTRL_CH(fan_tach_ch), reg_value); ++ } else ++ regmap_update_bits(priv->regmap, ASPEED_TACHO_CTRL_CH(fan_tach_ch), TACHO_ENABLE, 0); ++} ++ ++static void aspeed_set_pwm_channel_fan_ctrl(struct aspeed_pwm_tachometer_data *priv, ++ u8 index, u8 fan_ctrl) ++{ ++ u32 duty_value, ctrl_value; ++ ++ if (fan_ctrl == 0) { ++ aspeed_set_pwm_channel_enable(priv->regmap, index, false); ++ } else { ++ duty_value = (priv->pwm_channel[index].period << PWM_PERIOD_BIT) | ++ (0 << PWM_RISING_RISING_BIT) | (fan_ctrl << PWM_RISING_FALLING_BIT); ++ ++ ctrl_value = (priv->pwm_channel[index].divide_h << 8) | priv->pwm_channel[index].divide_l; ++ ++ if (priv->pwm_channel[index].load_wdt_enable) { ++ ctrl_value |= PWM_DUTY_LOAD_AS_WDT_EN; ++ if(priv->pwm_channel[index].load_wdt_selection) { ++ ctrl_value |= PWM_LOAD_AS_WDT; ++ duty_value |= (priv->pwm_channel[index].load_wdt_rising_falling_pt << PWM_RISING_FALLING_AS_WDT_BIT); ++ } else { ++ duty_value |= (priv->pwm_channel[index].load_wdt_rising_falling_pt << PWM_RISING_FALLING_AS_WDT_BIT); ++ } ++ } ++ ++ regmap_write(priv->regmap, ASPEED_PWM_DUTY_CYCLE_CH(index), duty_value); ++ ++ regmap_write(priv->regmap, ASPEED_PWM_CTRL_CH(index), ctrl_value); ++// printk("pwm clk is %d \n", priv->clk_freq / (priv->pwm_channel[index].period + 1)); ++ aspeed_set_pwm_channel_enable(priv->regmap, index, true); ++ } ++} ++ ++#define BOTH_EDGES 0x02 /* 10b */ ++ ++static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tachometer_data *priv, ++ u8 fan_tach_ch) ++{ ++ u32 raw_data, tach_div, clk_source, val; ++ u8 mode, both; ++ int i, retries = 3; ++ ++ for(i = 0; i < retries; i++) { ++ regmap_read(priv->regmap, ASPEED_TACHO_STS_CH(fan_tach_ch), &val); ++ if (TACHO_FULL_MEASUREMENT & val) ++ break; ++ } ++ ++ raw_data = val & TACHO_VALUE_MASK; ++ if(raw_data == 0xfffff) ++ return 0; ++ ++ tach_div = priv->tacho_channel[fan_tach_ch].divide; ++ /* ++ * We need the mode to determine if the raw_data is double (from ++ * counting both edges). ++ */ ++ mode = priv->tacho_channel[fan_tach_ch].tacho_edge; ++ both = (mode & BOTH_EDGES) ? 1 : 0; ++// printk("clk %ld, raw_data %x , tach_div %x both %x \n", priv->clk_freq, raw_data, tach_div, both); ++ ++ tach_div = (tach_div * 2) * (0x1 << both); ++ clk_source = priv->clk_freq; ++ ++ if (raw_data == 0) ++ return 0; ++ ++ return (clk_source * 60) / (2 * raw_data * tach_div); ++ ++} ++ ++static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int index = sensor_attr->index; ++ int ret; ++ struct aspeed_pwm_tachometer_data *priv = dev_get_drvdata(dev); ++ long fan_ctrl; ++ ++ ret = kstrtol(buf, 10, &fan_ctrl); ++ if (ret != 0) ++ return ret; ++ ++ if (fan_ctrl < 0 || fan_ctrl > priv->pwm_channel[index].period) ++ return -EINVAL; ++ ++ if (priv->pwm_channel[index].falling == fan_ctrl) ++ return count; ++ ++ priv->pwm_channel[index].falling = fan_ctrl; ++ aspeed_set_pwm_channel_fan_ctrl(priv, index, fan_ctrl); ++ ++ return count; ++} ++ ++static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int index = sensor_attr->index; ++ struct aspeed_pwm_tachometer_data *priv = dev_get_drvdata(dev); ++ ++ return sprintf(buf, "%u\n", priv->pwm_channel[index].falling); ++} ++ ++static ssize_t show_rpm(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); ++ int index = sensor_attr->index; ++ int rpm; ++ struct aspeed_pwm_tachometer_data *priv = dev_get_drvdata(dev); ++ ++ rpm = aspeed_get_fan_tach_ch_rpm(priv, index); ++ if (rpm < 0) ++ return rpm; ++ ++ return sprintf(buf, "%d\n", rpm); ++} ++ ++static umode_t pwm_is_visible(struct kobject *kobj, ++ struct attribute *a, int index) ++{ ++ struct device *dev = container_of(kobj, struct device, kobj); ++ struct aspeed_pwm_tachometer_data *priv = dev_get_drvdata(dev); ++ ++ if (!priv->pwm_present[index]) ++ return 0; ++ return a->mode; ++} ++ ++static umode_t fan_dev_is_visible(struct kobject *kobj, ++ struct attribute *a, int index) ++{ ++ struct device *dev = container_of(kobj, struct device, kobj); ++ struct aspeed_pwm_tachometer_data *priv = dev_get_drvdata(dev); ++ ++ if (!priv->fan_tach_present[index]) ++ return 0; ++ return a->mode; ++} ++ ++static SENSOR_DEVICE_ATTR(pwm0, 0644, ++ show_pwm, set_pwm, 0); ++static SENSOR_DEVICE_ATTR(pwm1, 0644, ++ show_pwm, set_pwm, 1); ++static SENSOR_DEVICE_ATTR(pwm2, 0644, ++ show_pwm, set_pwm, 2); ++static SENSOR_DEVICE_ATTR(pwm3, 0644, ++ show_pwm, set_pwm, 3); ++static SENSOR_DEVICE_ATTR(pwm4, 0644, ++ show_pwm, set_pwm, 4); ++static SENSOR_DEVICE_ATTR(pwm5, 0644, ++ show_pwm, set_pwm, 5); ++static SENSOR_DEVICE_ATTR(pwm6, 0644, ++ show_pwm, set_pwm, 6); ++static SENSOR_DEVICE_ATTR(pwm7, 0644, ++ show_pwm, set_pwm, 7); ++static SENSOR_DEVICE_ATTR(pwm8, 0644, ++ show_pwm, set_pwm, 8); ++static SENSOR_DEVICE_ATTR(pwm9, 0644, ++ show_pwm, set_pwm, 9); ++static SENSOR_DEVICE_ATTR(pwm10, 0644, ++ show_pwm, set_pwm, 10); ++static SENSOR_DEVICE_ATTR(pwm11, 0644, ++ show_pwm, set_pwm, 11); ++static SENSOR_DEVICE_ATTR(pwm12, 0644, ++ show_pwm, set_pwm, 12); ++static SENSOR_DEVICE_ATTR(pwm13, 0644, ++ show_pwm, set_pwm, 13); ++static SENSOR_DEVICE_ATTR(pwm14, 0644, ++ show_pwm, set_pwm, 14); ++static SENSOR_DEVICE_ATTR(pwm15, 0644, ++ show_pwm, set_pwm, 15); ++static struct attribute *pwm_dev_attrs[] = { ++ &sensor_dev_attr_pwm0.dev_attr.attr, ++ &sensor_dev_attr_pwm1.dev_attr.attr, ++ &sensor_dev_attr_pwm2.dev_attr.attr, ++ &sensor_dev_attr_pwm3.dev_attr.attr, ++ &sensor_dev_attr_pwm4.dev_attr.attr, ++ &sensor_dev_attr_pwm5.dev_attr.attr, ++ &sensor_dev_attr_pwm6.dev_attr.attr, ++ &sensor_dev_attr_pwm7.dev_attr.attr, ++ &sensor_dev_attr_pwm8.dev_attr.attr, ++ &sensor_dev_attr_pwm9.dev_attr.attr, ++ &sensor_dev_attr_pwm10.dev_attr.attr, ++ &sensor_dev_attr_pwm11.dev_attr.attr, ++ &sensor_dev_attr_pwm12.dev_attr.attr, ++ &sensor_dev_attr_pwm13.dev_attr.attr, ++ &sensor_dev_attr_pwm14.dev_attr.attr, ++ &sensor_dev_attr_pwm15.dev_attr.attr, ++ NULL, ++}; ++ ++static const struct attribute_group pwm_dev_group = { ++ .attrs = pwm_dev_attrs, ++ .is_visible = pwm_is_visible, ++}; ++ ++static SENSOR_DEVICE_ATTR(fan0_input, 0444, ++ show_rpm, NULL, 0); ++static SENSOR_DEVICE_ATTR(fan1_input, 0444, ++ show_rpm, NULL, 1); ++static SENSOR_DEVICE_ATTR(fan2_input, 0444, ++ show_rpm, NULL, 2); ++static SENSOR_DEVICE_ATTR(fan3_input, 0444, ++ show_rpm, NULL, 3); ++static SENSOR_DEVICE_ATTR(fan4_input, 0444, ++ show_rpm, NULL, 4); ++static SENSOR_DEVICE_ATTR(fan5_input, 0444, ++ show_rpm, NULL, 5); ++static SENSOR_DEVICE_ATTR(fan6_input, 0444, ++ show_rpm, NULL, 6); ++static SENSOR_DEVICE_ATTR(fan7_input, 0444, ++ show_rpm, NULL, 7); ++static SENSOR_DEVICE_ATTR(fan8_input, 0444, ++ show_rpm, NULL, 8); ++static SENSOR_DEVICE_ATTR(fan9_input, 0444, ++ show_rpm, NULL, 9); ++static SENSOR_DEVICE_ATTR(fan10_input, 0444, ++ show_rpm, NULL, 10); ++static SENSOR_DEVICE_ATTR(fan11_input, 0444, ++ show_rpm, NULL, 11); ++static SENSOR_DEVICE_ATTR(fan12_input, 0444, ++ show_rpm, NULL, 12); ++static SENSOR_DEVICE_ATTR(fan13_input, 0444, ++ show_rpm, NULL, 13); ++static SENSOR_DEVICE_ATTR(fan14_input, 0444, ++ show_rpm, NULL, 14); ++static SENSOR_DEVICE_ATTR(fan15_input, 0444, ++ show_rpm, NULL, 15); ++static struct attribute *fan_dev_attrs[] = { ++ &sensor_dev_attr_fan0_input.dev_attr.attr, ++ &sensor_dev_attr_fan1_input.dev_attr.attr, ++ &sensor_dev_attr_fan2_input.dev_attr.attr, ++ &sensor_dev_attr_fan3_input.dev_attr.attr, ++ &sensor_dev_attr_fan4_input.dev_attr.attr, ++ &sensor_dev_attr_fan5_input.dev_attr.attr, ++ &sensor_dev_attr_fan6_input.dev_attr.attr, ++ &sensor_dev_attr_fan7_input.dev_attr.attr, ++ &sensor_dev_attr_fan8_input.dev_attr.attr, ++ &sensor_dev_attr_fan9_input.dev_attr.attr, ++ &sensor_dev_attr_fan10_input.dev_attr.attr, ++ &sensor_dev_attr_fan11_input.dev_attr.attr, ++ &sensor_dev_attr_fan12_input.dev_attr.attr, ++ &sensor_dev_attr_fan13_input.dev_attr.attr, ++ &sensor_dev_attr_fan14_input.dev_attr.attr, ++ &sensor_dev_attr_fan15_input.dev_attr.attr, ++ NULL ++}; ++ ++static const struct attribute_group fan_dev_group = { ++ .attrs = fan_dev_attrs, ++ .is_visible = fan_dev_is_visible, ++}; ++ ++static void aspeed_create_pwm_channel(struct aspeed_pwm_tachometer_data *priv, ++ u8 pwm_channel) ++{ ++ priv->pwm_present[pwm_channel] = true; ++ ++ //use default ++ aspeed_set_pwm_channel_fan_ctrl(priv, pwm_channel, priv->pwm_channel[pwm_channel].falling); ++} ++ ++static void aspeed_create_fan_tach_channel(struct aspeed_pwm_tachometer_data *priv, ++ u8 *fan_tach_ch, ++ int count) ++{ ++ u8 val, index; ++ ++ for (val = 0; val < count; val++) { ++ index = fan_tach_ch[val]; ++ priv->fan_tach_present[index] = true; ++ aspeed_set_fan_tach_ch_enable(priv, index, true); ++ } ++} ++ ++static int ++aspeed_pwm_cz_get_max_state(struct thermal_cooling_device *tcdev, ++ unsigned long *state) ++{ ++ struct aspeed_cooling_device *cdev = tcdev->devdata; ++ ++ *state = cdev->max_state; ++ ++ return 0; ++} ++ ++static int ++aspeed_pwm_cz_get_cur_state(struct thermal_cooling_device *tcdev, ++ unsigned long *state) ++{ ++ struct aspeed_cooling_device *cdev = tcdev->devdata; ++ ++ *state = cdev->cur_state; ++ ++ return 0; ++} ++ ++static int ++aspeed_pwm_cz_set_cur_state(struct thermal_cooling_device *tcdev, ++ unsigned long state) ++{ ++ struct aspeed_cooling_device *cdev = tcdev->devdata; ++ ++ if (state > cdev->max_state) ++ return -EINVAL; ++ ++ cdev->cur_state = state; ++ cdev->priv->pwm_channel[cdev->pwm_channel].falling = ++ cdev->cooling_levels[cdev->cur_state]; ++ aspeed_set_pwm_channel_fan_ctrl(cdev->priv, cdev->pwm_channel, ++ cdev->cooling_levels[cdev->cur_state]); ++ ++ return 0; ++} ++ ++static const struct thermal_cooling_device_ops aspeed_pwm_cool_ops = { ++ .get_max_state = aspeed_pwm_cz_get_max_state, ++ .get_cur_state = aspeed_pwm_cz_get_cur_state, ++ .set_cur_state = aspeed_pwm_cz_set_cur_state, ++}; ++ ++static int aspeed_create_pwm_cooling(struct device *dev, ++ struct device_node *child, ++ struct aspeed_pwm_tachometer_data *priv, ++ u32 pwm_channel, u8 num_levels) ++{ ++ int ret; ++ struct aspeed_cooling_device *cdev; ++ ++ cdev = devm_kzalloc(dev, sizeof(*cdev), GFP_KERNEL); ++ if (!cdev) ++ return -ENOMEM; ++ ++ cdev->cooling_levels = devm_kzalloc(dev, num_levels, GFP_KERNEL); ++ if (!cdev->cooling_levels) ++ return -ENOMEM; ++ ++ cdev->max_state = num_levels - 1; ++ ret = of_property_read_u8_array(child, "cooling-levels", ++ cdev->cooling_levels, ++ num_levels); ++ if (ret) { ++ dev_err(dev, "Property 'cooling-levels' cannot be read.\n"); ++ return ret; ++ } ++ snprintf(cdev->name, MAX_CDEV_NAME_LEN, "%s%d", child->name, pwm_channel); ++ ++ cdev->tcdev = thermal_of_cooling_device_register(child, ++ cdev->name, ++ cdev, ++ &aspeed_pwm_cool_ops); ++ if (IS_ERR(cdev->tcdev)) ++ return PTR_ERR(cdev->tcdev); ++ ++ cdev->priv = priv; ++ cdev->pwm_channel = pwm_channel; ++ ++ priv->cdev[pwm_channel] = cdev; ++ ++ return 0; ++} ++ ++static int aspeed_pwm_create_fan(struct device *dev, ++ struct device_node *child, ++ struct aspeed_pwm_tachometer_data *priv) ++{ ++ u8 *fan_tach_ch; ++ u32 pwm_channel; ++ int ret, count; ++ ++ ret = of_property_read_u32(child, "reg", &pwm_channel); ++ if (ret) ++ return ret; ++ ++ aspeed_create_pwm_channel(priv, (u8)pwm_channel); ++ ++ ret = of_property_count_u8_elems(child, "cooling-levels"); ++ if (ret > 0) { ++ ret = aspeed_create_pwm_cooling(dev, child, priv, pwm_channel, ++ ret); ++ if (ret) ++ return ret; ++ } ++ ++ count = of_property_count_u8_elems(child, "aspeed,fan-tach-ch"); ++ if (count < 1) ++ return -EINVAL; ++ ++ fan_tach_ch = devm_kzalloc(dev, sizeof(*fan_tach_ch) * count, ++ GFP_KERNEL); ++ if (!fan_tach_ch) ++ return -ENOMEM; ++ ret = of_property_read_u8_array(child, "aspeed,fan-tach-ch", ++ fan_tach_ch, count); ++ if (ret) ++ return ret; ++ ++ aspeed_create_fan_tach_channel(priv, fan_tach_ch, count); ++ ++ return 0; ++} ++ ++static int aspeed_pwm_tachometer_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np, *child; ++ struct aspeed_pwm_tachometer_data *priv; ++ void __iomem *regs; ++ struct resource *res; ++ struct device *hwmon; ++ struct clk *clk; ++ int ret; ++ ++ np = dev->of_node; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -ENOENT; ++ regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(regs)) ++ return PTR_ERR(regs); ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ priv->pwm_channel = default_pwm_params; ++ priv->tacho_channel = default_tacho_params; ++ priv->regmap = devm_regmap_init(dev, NULL, (__force void *)regs, ++ &aspeed_pwm_tachometer_regmap_config); ++ if (IS_ERR(priv->regmap)) ++ return PTR_ERR(priv->regmap); ++ ++ clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(clk)) ++ return -ENODEV; ++ priv->clk_freq = clk_get_rate(clk); ++ ++ priv->reset = devm_reset_control_get(&pdev->dev, NULL); ++ if (IS_ERR(priv->reset)) { ++ dev_err(&pdev->dev, "can't get aspeed_pwm_tacho reset\n"); ++ return PTR_ERR(priv->reset); ++ } ++ ++ //scu init ++ reset_control_assert(priv->reset); ++ reset_control_deassert(priv->reset); ++ ++ for_each_child_of_node(np, child) { ++ ret = aspeed_pwm_create_fan(dev, child, priv); ++ if (ret) { ++ of_node_put(child); ++ return ret; ++ } ++ } ++ ++ priv->groups[0] = &pwm_dev_group; ++ priv->groups[1] = &fan_dev_group; ++ priv->groups[2] = NULL; ++ hwmon = devm_hwmon_device_register_with_groups(dev, ++ "aspeed_g6_pwm_tacho", ++ priv, priv->groups); ++ ++ return PTR_ERR_OR_ZERO(hwmon); ++} ++ ++static const struct of_device_id of_pwm_tachometer_match_table[] = { ++ { .compatible = "aspeed,ast2600-pwm-tacho", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, of_pwm_tachometer_match_table); ++ ++static struct platform_driver aspeed_pwm_tachometer_driver = { ++ .probe = aspeed_pwm_tachometer_probe, ++ .driver = { ++ .name = "aspeed_g6_pwm_tacho", ++ .of_match_table = of_pwm_tachometer_match_table, ++ }, ++}; ++ ++module_platform_driver(aspeed_pwm_tachometer_driver); ++ ++MODULE_AUTHOR("Ryan Chen "); ++MODULE_DESCRIPTION("ASPEED PWM and Fan Tachometer device driver"); ++MODULE_LICENSE("GPL"); +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0078-Fix-NCSI-driver-issue-caused-by-host-shutdown.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0078-Fix-NCSI-driver-issue-caused-by-host-shutdown.patch new file mode 100644 index 000000000..c02131b6a --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0078-Fix-NCSI-driver-issue-caused-by-host-shutdown.patch @@ -0,0 +1,70 @@ +From 3e698a7666ec54582d0e2b4842f3e7f27fabe303 Mon Sep 17 00:00:00 2001 +From: Kuiying Wang +Date: Tue, 29 Oct 2019 11:28:29 +0800 +Subject: [PATCH] Fix NCSI driver issue caused by host shutdown due to + overheated. + +NCSI device cannot be recovered when host shutdown due to overheated. + +Tested: +Heat host till shutdown due to overheated and then +run the ipmi command like power status + +Signed-off-by: Kuiying Wang +--- + net/ncsi/ncsi-manage.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c +index 755aab66dcab..2c5294582ef6 100644 +--- a/net/ncsi/ncsi-manage.c ++++ b/net/ncsi/ncsi-manage.c +@@ -133,18 +133,15 @@ static void ncsi_channel_monitor(struct timer_list *t) + netdev_err(ndp->ndev.dev, "NCSI Channel %d timed out!\n", + nc->id); + ncsi_report_link(ndp, true); +- ndp->flags |= NCSI_DEV_RESHUFFLE; + + ncsi_stop_channel_monitor(nc); + +- ncm = &nc->modes[NCSI_MODE_LINK]; + spin_lock_irqsave(&nc->lock, flags); +- nc->state = NCSI_CHANNEL_INVISIBLE; +- ncm->data[2] &= ~0x1; ++ nc->state = NCSI_CHANNEL_INACTIVE; + spin_unlock_irqrestore(&nc->lock, flags); + + spin_lock_irqsave(&ndp->lock, flags); +- nc->state = NCSI_CHANNEL_ACTIVE; ++ ndp->flags |= NCSI_DEV_RESHUFFLE | NCSI_DEV_RESET; + list_add_tail_rcu(&nc->link, &ndp->channel_queue); + spin_unlock_irqrestore(&ndp->lock, flags); + ncsi_process_next_channel(ndp); +@@ -425,6 +422,7 @@ static void ncsi_request_timeout(struct timer_list *t) + { + struct ncsi_request *nr = from_timer(nr, t, timer); + struct ncsi_dev_priv *ndp = nr->ndp; ++ struct ncsi_dev *nd = &ndp->ndev; + struct ncsi_cmd_pkt *cmd; + struct ncsi_package *np; + struct ncsi_channel *nc; +@@ -439,6 +437,16 @@ static void ncsi_request_timeout(struct timer_list *t) + spin_unlock_irqrestore(&ndp->lock, flags); + return; + } ++ if (nd->state == ncsi_dev_state_suspend || ++ nd->state == ncsi_dev_state_suspend_select || ++ nd->state == ncsi_dev_state_suspend_gls || ++ nd->state == ncsi_dev_state_suspend_dcnt || ++ nd->state == ncsi_dev_state_suspend_dc || ++ nd->state == ncsi_dev_state_suspend_deselect || ++ nd->state == ncsi_dev_state_suspend_done) { ++ ndp->flags |= NCSI_DEV_RESET; ++ nd->state = ncsi_dev_state_suspend_done; ++ } + spin_unlock_irqrestore(&ndp->lock, flags); + + if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) { +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0079-usb-gadget-aspeed-backport-aspeed-vhub-bug-fixes.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0079-usb-gadget-aspeed-backport-aspeed-vhub-bug-fixes.patch new file mode 100644 index 000000000..17db705d1 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0079-usb-gadget-aspeed-backport-aspeed-vhub-bug-fixes.patch @@ -0,0 +1,473 @@ +From 0475ac3698cf3d95d78b0230418ec7ef5fdc62c7 Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo +Date: Tue, 29 Oct 2019 11:42:08 -0700 +Subject: [PATCH] usb: gadget: aspeed: backport aspeed vhub bug fixes + +usb: gadget: aspeed: Implement dummy hub TT requests + +We just accept them instead of stalling and return +zeros on GetTTState. + +usb: Add definitions for the USB2.0 hub TT requests + +usb: gadget: aspeed: Improve debugging when nuking + +When nuking requests, it's useful to display how many were +actually nuked. It has proven handy when debugging issues +where EP0 went in a wrong state. + +usb: gadget: aspeed: Remove unused "suspended" flag + +The state bit in the hub is sufficient + +usb: gadget: aspeed: Rework the reset logic + +We had some dodgy code using the speed setting to decide whether a +port reset would reset the device or just enable it. + +Instead, if the device is disabled and has a gadget attached, a +reset will enable it. If it's already enabled, a reset will +reset it. + +usb: gadget: aspeed: Check suspend/resume callback existence + +.. before calling them + +usb: gadget: aspeed: Don't reject requests on suspended devices + +A disconnect may just suspend the hub in absence of a physical +disconnect detection. If we start rejecting requests, the mass +storage function gets into a spin trying to requeue the same +request for ever and hangs. + +usb: gadget: aspeed: Fix EP0 stall handling + +When stalling EP0, we need to wait for an ACK interrupt, +otherwise we may get out of sync on the next setup packet +data phase. Also we need to ignore the direction when +processing that interrupt as the HW reports a potential +mismatch. + +Implement this by adding a stall state to EP0. This fixes +some reported issues with mass storage and some hosts. + +usb: gadget: aspeed: Cleanup EP0 state on port reset + +Otherwise, we can have a stale state after a disconnect and reconnect +causing errors on the first SETUP packet to the device. + +causing errors on the first SETUP packet to the device. + +usb: gadget: aspeed: Don't set port enable change bit on reset + +This bit should be only set when the port enable goes down, for +example, on errors. Not when it gets set after a port reset. Some +USB stacks seem to be sensitive to this and fails enumeration. + +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Felipe Balbi +Signed-off-by: Jae Hyun Yoo +--- + drivers/usb/gadget/udc/aspeed-vhub/core.c | 7 +-- + drivers/usb/gadget/udc/aspeed-vhub/dev.c | 80 +++++++++++++++---------------- + drivers/usb/gadget/udc/aspeed-vhub/ep0.c | 59 ++++++++++++++++------- + drivers/usb/gadget/udc/aspeed-vhub/epn.c | 2 +- + drivers/usb/gadget/udc/aspeed-vhub/hub.c | 15 +++++- + drivers/usb/gadget/udc/aspeed-vhub/vhub.h | 3 +- + include/linux/usb/hcd.h | 4 ++ + 7 files changed, 107 insertions(+), 63 deletions(-) + +diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c b/drivers/usb/gadget/udc/aspeed-vhub/core.c +index db3628be38c0..90b134d5dca9 100644 +--- a/drivers/usb/gadget/udc/aspeed-vhub/core.c ++++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c +@@ -65,14 +65,16 @@ void ast_vhub_done(struct ast_vhub_ep *ep, struct ast_vhub_req *req, + void ast_vhub_nuke(struct ast_vhub_ep *ep, int status) + { + struct ast_vhub_req *req; +- +- EPDBG(ep, "Nuking\n"); ++ int count = 0; + + /* Beware, lock will be dropped & req-acquired by done() */ + while (!list_empty(&ep->queue)) { + req = list_first_entry(&ep->queue, struct ast_vhub_req, queue); + ast_vhub_done(ep, req, status); ++ count++; + } ++ if (count) ++ EPDBG(ep, "Nuked %d request(s)\n", count); + } + + struct usb_request *ast_vhub_alloc_request(struct usb_ep *u_ep, +@@ -348,7 +350,6 @@ static int ast_vhub_probe(struct platform_device *pdev) + /* Find interrupt and install handler */ + vhub->irq = platform_get_irq(pdev, 0); + if (vhub->irq < 0) { +- dev_err(&pdev->dev, "Failed to get interrupt\n"); + rc = vhub->irq; + goto err; + } +diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c +index 6b1b16b17d7d..4008e7a51188 100644 +--- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c ++++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c +@@ -50,11 +50,14 @@ void ast_vhub_dev_irq(struct ast_vhub_dev *d) + + static void ast_vhub_dev_enable(struct ast_vhub_dev *d) + { +- u32 reg, hmsk; ++ u32 reg, hmsk, i; + + if (d->enabled) + return; + ++ /* Cleanup EP0 state */ ++ ast_vhub_reset_ep0(d); ++ + /* Enable device and its EP0 interrupts */ + reg = VHUB_DEV_EN_ENABLE_PORT | + VHUB_DEV_EN_EP0_IN_ACK_IRQEN | +@@ -73,6 +76,19 @@ static void ast_vhub_dev_enable(struct ast_vhub_dev *d) + /* Set EP0 DMA buffer address */ + writel(d->ep0.buf_dma, d->regs + AST_VHUB_DEV_EP0_DATA); + ++ /* Clear stall on all EPs */ ++ for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++) { ++ struct ast_vhub_ep *ep = d->epns[i]; ++ ++ if (ep && (ep->epn.stalled || ep->epn.wedged)) { ++ ep->epn.stalled = false; ++ ep->epn.wedged = false; ++ ast_vhub_update_epn_stall(ep); ++ } ++ } ++ ++ /* Additional cleanups */ ++ d->wakeup_en = false; + d->enabled = true; + } + +@@ -93,7 +109,6 @@ static void ast_vhub_dev_disable(struct ast_vhub_dev *d) + writel(0, d->regs + AST_VHUB_DEV_EN_CTRL); + d->gadget.speed = USB_SPEED_UNKNOWN; + d->enabled = false; +- d->suspended = false; + } + + static int ast_vhub_dev_feature(struct ast_vhub_dev *d, +@@ -201,14 +216,19 @@ int ast_vhub_std_dev_request(struct ast_vhub_ep *ep, + u16 wValue, wIndex; + + /* No driver, we shouldn't be enabled ... */ +- if (!d->driver || !d->enabled || d->suspended) { ++ if (!d->driver || !d->enabled) { + EPDBG(ep, +- "Device is wrong state driver=%p enabled=%d" +- " suspended=%d\n", +- d->driver, d->enabled, d->suspended); ++ "Device is wrong state driver=%p enabled=%d\n", ++ d->driver, d->enabled); + return std_req_stall; + } + ++ /* ++ * Note: we used to reject/stall requests while suspended, ++ * we don't do that anymore as we seem to have cases of ++ * mass storage getting very upset. ++ */ ++ + /* First packet, grab speed */ + if (d->gadget.speed == USB_SPEED_UNKNOWN) { + d->gadget.speed = ep->vhub->speed; +@@ -449,8 +469,7 @@ static const struct usb_gadget_ops ast_vhub_udc_ops = { + + void ast_vhub_dev_suspend(struct ast_vhub_dev *d) + { +- d->suspended = true; +- if (d->driver) { ++ if (d->driver && d->driver->suspend) { + spin_unlock(&d->vhub->lock); + d->driver->suspend(&d->gadget); + spin_lock(&d->vhub->lock); +@@ -459,8 +478,7 @@ void ast_vhub_dev_suspend(struct ast_vhub_dev *d) + + void ast_vhub_dev_resume(struct ast_vhub_dev *d) + { +- d->suspended = false; +- if (d->driver) { ++ if (d->driver && d->driver->resume) { + spin_unlock(&d->vhub->lock); + d->driver->resume(&d->gadget); + spin_lock(&d->vhub->lock); +@@ -469,46 +487,28 @@ void ast_vhub_dev_resume(struct ast_vhub_dev *d) + + void ast_vhub_dev_reset(struct ast_vhub_dev *d) + { +- /* +- * If speed is not set, we enable the port. If it is, +- * send reset to the gadget and reset "speed". +- * +- * Speed is an indication that we have got the first +- * setup packet to the device. +- */ +- if (d->gadget.speed == USB_SPEED_UNKNOWN && !d->enabled) { +- DDBG(d, "Reset at unknown speed of disabled device, enabling...\n"); +- ast_vhub_dev_enable(d); +- d->suspended = false; ++ /* No driver, just disable the device and return */ ++ if (!d->driver) { ++ ast_vhub_dev_disable(d); ++ return; + } +- if (d->gadget.speed != USB_SPEED_UNKNOWN && d->driver) { +- unsigned int i; + +- DDBG(d, "Reset at known speed of bound device, resetting...\n"); ++ /* If the port isn't enabled, just enable it */ ++ if (!d->enabled) { ++ DDBG(d, "Reset of disabled device, enabling...\n"); ++ ast_vhub_dev_enable(d); ++ } else { ++ DDBG(d, "Reset of enabled device, resetting...\n"); + spin_unlock(&d->vhub->lock); +- d->driver->reset(&d->gadget); ++ usb_gadget_udc_reset(&d->gadget, d->driver); + spin_lock(&d->vhub->lock); + + /* +- * Disable/re-enable HW, this will clear the address ++ * Disable and maybe re-enable HW, this will clear the address + * and speed setting. + */ + ast_vhub_dev_disable(d); + ast_vhub_dev_enable(d); +- +- /* Clear stall on all EPs */ +- for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++) { +- struct ast_vhub_ep *ep = d->epns[i]; +- +- if (ep && ep->epn.stalled) { +- ep->epn.stalled = false; +- ast_vhub_update_epn_stall(ep); +- } +- } +- +- /* Additional cleanups */ +- d->wakeup_en = false; +- d->suspended = false; + } + } + +diff --git a/drivers/usb/gadget/udc/aspeed-vhub/ep0.c b/drivers/usb/gadget/udc/aspeed-vhub/ep0.c +index e2927fb083cf..022b777b85f8 100644 +--- a/drivers/usb/gadget/udc/aspeed-vhub/ep0.c ++++ b/drivers/usb/gadget/udc/aspeed-vhub/ep0.c +@@ -105,18 +105,20 @@ void ast_vhub_ep0_handle_setup(struct ast_vhub_ep *ep) + (crq.bRequestType & USB_DIR_IN) ? "in" : "out", + ep->ep0.state); + +- /* Check our state, cancel pending requests if needed */ +- if (ep->ep0.state != ep0_state_token) { ++ /* ++ * Check our state, cancel pending requests if needed ++ * ++ * Note: Under some circumstances, we can get a new setup ++ * packet while waiting for the stall ack, just accept it. ++ * ++ * In any case, a SETUP packet in wrong state should have ++ * reset the HW state machine, so let's just log, nuke ++ * requests, move on. ++ */ ++ if (ep->ep0.state != ep0_state_token && ++ ep->ep0.state != ep0_state_stall) { + EPDBG(ep, "wrong state\n"); + ast_vhub_nuke(ep, -EIO); +- +- /* +- * Accept the packet regardless, this seems to happen +- * when stalling a SETUP packet that has an OUT data +- * phase. +- */ +- ast_vhub_nuke(ep, 0); +- goto stall; + } + + /* Calculate next state for EP0 */ +@@ -165,7 +167,7 @@ void ast_vhub_ep0_handle_setup(struct ast_vhub_ep *ep) + stall: + EPDBG(ep, "stalling\n"); + writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat); +- ep->ep0.state = ep0_state_status; ++ ep->ep0.state = ep0_state_stall; + ep->ep0.dir_in = false; + return; + +@@ -299,8 +301,8 @@ void ast_vhub_ep0_handle_ack(struct ast_vhub_ep *ep, bool in_ack) + if ((ep->ep0.dir_in && (stat & VHUB_EP0_TX_BUFF_RDY)) || + (!ep->ep0.dir_in && (stat & VHUB_EP0_RX_BUFF_RDY)) || + (ep->ep0.dir_in != in_ack)) { ++ /* In that case, ignore interrupt */ + dev_warn(dev, "irq state mismatch"); +- stall = true; + break; + } + /* +@@ -335,12 +337,22 @@ void ast_vhub_ep0_handle_ack(struct ast_vhub_ep *ep, bool in_ack) + dev_warn(dev, "status direction mismatch\n"); + stall = true; + } ++ break; ++ case ep0_state_stall: ++ /* ++ * There shouldn't be any request left, but nuke just in case ++ * otherwise the stale request will block subsequent ones ++ */ ++ ast_vhub_nuke(ep, -EIO); ++ break; + } + +- /* Reset to token state */ +- ep->ep0.state = ep0_state_token; +- if (stall) ++ /* Reset to token state or stall */ ++ if (stall) { + writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat); ++ ep->ep0.state = ep0_state_stall; ++ } else ++ ep->ep0.state = ep0_state_token; + } + + static int ast_vhub_ep0_queue(struct usb_ep* u_ep, struct usb_request *u_req, +@@ -367,7 +379,7 @@ static int ast_vhub_ep0_queue(struct usb_ep* u_ep, struct usb_request *u_req, + return -EINVAL; + + /* Disabled device */ +- if (ep->dev && (!ep->dev->enabled || ep->dev->suspended)) ++ if (ep->dev && !ep->dev->enabled) + return -ESHUTDOWN; + + /* Data, no buffer and not internal ? */ +@@ -390,8 +402,12 @@ static int ast_vhub_ep0_queue(struct usb_ep* u_ep, struct usb_request *u_req, + spin_lock_irqsave(&vhub->lock, flags); + + /* EP0 can only support a single request at a time */ +- if (!list_empty(&ep->queue) || ep->ep0.state == ep0_state_token) { ++ if (!list_empty(&ep->queue) || ++ ep->ep0.state == ep0_state_token || ++ ep->ep0.state == ep0_state_stall) { + dev_warn(dev, "EP0: Request in wrong state\n"); ++ EPVDBG(ep, "EP0: list_empty=%d state=%d\n", ++ list_empty(&ep->queue), ep->ep0.state); + spin_unlock_irqrestore(&vhub->lock, flags); + return -EBUSY; + } +@@ -459,6 +475,15 @@ static const struct usb_ep_ops ast_vhub_ep0_ops = { + .free_request = ast_vhub_free_request, + }; + ++void ast_vhub_reset_ep0(struct ast_vhub_dev *dev) ++{ ++ struct ast_vhub_ep *ep = &dev->ep0; ++ ++ ast_vhub_nuke(ep, -EIO); ++ ep->ep0.state = ep0_state_token; ++} ++ ++ + void ast_vhub_init_ep0(struct ast_vhub *vhub, struct ast_vhub_ep *ep, + struct ast_vhub_dev *dev) + { +diff --git a/drivers/usb/gadget/udc/aspeed-vhub/epn.c b/drivers/usb/gadget/udc/aspeed-vhub/epn.c +index 35941dc125f9..7475c74aa5c5 100644 +--- a/drivers/usb/gadget/udc/aspeed-vhub/epn.c ++++ b/drivers/usb/gadget/udc/aspeed-vhub/epn.c +@@ -352,7 +352,7 @@ static int ast_vhub_epn_queue(struct usb_ep* u_ep, struct usb_request *u_req, + + /* Endpoint enabled ? */ + if (!ep->epn.enabled || !u_ep->desc || !ep->dev || !ep->d_idx || +- !ep->dev->enabled || ep->dev->suspended) { ++ !ep->dev->enabled) { + EPDBG(ep, "Enqueuing request on wrong or disabled EP\n"); + return -ESHUTDOWN; + } +diff --git a/drivers/usb/gadget/udc/aspeed-vhub/hub.c b/drivers/usb/gadget/udc/aspeed-vhub/hub.c +index 7c040f56100e..19b3517e04c0 100644 +--- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c ++++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c +@@ -449,8 +449,15 @@ static void ast_vhub_change_port_stat(struct ast_vhub *vhub, + USB_PORT_STAT_C_OVERCURRENT | + USB_PORT_STAT_C_RESET | + USB_PORT_STAT_C_L1; +- p->change |= chg; + ++ /* ++ * We only set USB_PORT_STAT_C_ENABLE if we are disabling ++ * the port as per USB spec, otherwise MacOS gets upset ++ */ ++ if (p->status & USB_PORT_STAT_ENABLE) ++ chg &= ~USB_PORT_STAT_C_ENABLE; ++ ++ p->change = chg; + ast_vhub_update_hub_ep1(vhub, port); + } + } +@@ -723,6 +730,12 @@ enum std_req_rc ast_vhub_class_hub_request(struct ast_vhub_ep *ep, + case ClearPortFeature: + EPDBG(ep, "ClearPortFeature(%d,%d)\n", wIndex & 0xf, wValue); + return ast_vhub_clr_port_feature(ep, wIndex & 0xf, wValue); ++ case ClearTTBuffer: ++ case ResetTT: ++ case StopTT: ++ return std_req_complete; ++ case GetTTState: ++ return ast_vhub_simple_reply(ep, 0, 0, 0, 0); + default: + EPDBG(ep, "Unknown class request\n"); + } +diff --git a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h +index 4ed03d33a5a9..761919e220d3 100644 +--- a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h ++++ b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h +@@ -257,6 +257,7 @@ enum ep0_state { + ep0_state_token, + ep0_state_data, + ep0_state_status, ++ ep0_state_stall, + }; + + /* +@@ -353,7 +354,6 @@ struct ast_vhub_dev { + struct usb_gadget_driver *driver; + bool registered : 1; + bool wakeup_en : 1; +- bool suspended : 1; + bool enabled : 1; + + /* Endpoint structures */ +@@ -507,6 +507,7 @@ void ast_vhub_init_hw(struct ast_vhub *vhub); + /* ep0.c */ + void ast_vhub_ep0_handle_ack(struct ast_vhub_ep *ep, bool in_ack); + void ast_vhub_ep0_handle_setup(struct ast_vhub_ep *ep); ++void ast_vhub_reset_ep0(struct ast_vhub_dev *dev); + void ast_vhub_init_ep0(struct ast_vhub *vhub, struct ast_vhub_ep *ep, + struct ast_vhub_dev *dev); + int ast_vhub_reply(struct ast_vhub_ep *ep, char *ptr, int len); +diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h +index a20e7815d814..774a03028da2 100644 +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -594,6 +594,10 @@ extern void usb_ep0_reinit(struct usb_device *); + #define GetPortStatus HUB_CLASS_REQ(USB_DIR_IN, USB_RT_PORT, USB_REQ_GET_STATUS) + #define SetHubFeature HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_HUB, USB_REQ_SET_FEATURE) + #define SetPortFeature HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, USB_REQ_SET_FEATURE) ++#define ClearTTBuffer HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, HUB_CLEAR_TT_BUFFER) ++#define ResetTT HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, HUB_RESET_TT) ++#define GetTTState HUB_CLASS_REQ(USB_DIR_IN, USB_RT_PORT, HUB_GET_TT_STATE) ++#define StopTT HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, HUB_STOP_TT) + + + /*-------------------------------------------------------------------------*/ +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0080-i2c-aspeed-filter-garbage-interrupts-out.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0080-i2c-aspeed-filter-garbage-interrupts-out.patch new file mode 100644 index 000000000..0e32615d5 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0080-i2c-aspeed-filter-garbage-interrupts-out.patch @@ -0,0 +1,64 @@ +From 6825259fc0ac015c6544f6070ceaf9cc263c1853 Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo +Date: Fri, 8 Nov 2019 15:57:27 -0800 +Subject: [PATCH] i2c: aspeed: filter garbage interrupts out + +AST2600 makes a garbage interrupt which is decribed as 'reserved' +in datasheet so filter them out. + +Signed-off-by: Jae Hyun Yoo +--- + drivers/i2c/busses/i2c-aspeed.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c +index 62b803e15ce2..e7cba33c0c87 100644 +--- a/drivers/i2c/busses/i2c-aspeed.c ++++ b/drivers/i2c/busses/i2c-aspeed.c +@@ -87,7 +87,11 @@ + * These share bit definitions, so use the same values for the enable & + * status bits. + */ ++#if defined(CONFIG_MACH_ASPEED_G6) ++#define ASPEED_I2CD_INTR_SLAVE_ADDR_RECEIVED_PENDING BIT(29) ++#else + #define ASPEED_I2CD_INTR_SLAVE_ADDR_RECEIVED_PENDING BIT(30) ++#endif + #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) +@@ -118,6 +122,11 @@ + ASPEED_I2CD_INTR_RX_DONE | \ + ASPEED_I2CD_INTR_TX_NAK | \ + ASPEED_I2CD_INTR_TX_ACK) ++#define ASPEED_I2CD_INTR_STATUS_MASK \ ++ (ASPEED_I2CD_INTR_SLAVE_ADDR_RECEIVED_PENDING | \ ++ ASPEED_I2CD_INTR_GCALL_ADDR | \ ++ ASPEED_I2CD_INTR_SLAVE_MATCH | \ ++ ASPEED_I2CD_INTR_ALL) + + /* 0x14 : I2CD Command/Status Register */ + #define ASPEED_I2CD_SCL_LINE_STS BIT(18) +@@ -1018,9 +1027,19 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) + + spin_lock(&bus->lock); + irq_received = readl(bus->base + ASPEED_I2C_INTR_STS_REG); ++ if (!irq_received) { ++ spin_unlock(&bus->lock); ++ return IRQ_NONE; ++ } ++ + /* Ack all interrupts except for Rx done */ + writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE, + bus->base + ASPEED_I2C_INTR_STS_REG); ++ /* ++ * AST2600 makes a garbage interrupt which is decribed as 'reserved' ++ * in datasheet so filter them out. ++ */ ++ irq_received &= ASPEED_I2CD_INTR_STATUS_MASK; + irq_remaining = irq_received; + + #if IS_ENABLED(CONFIG_I2C_SLAVE) +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0081-clk-ast2600-enable-BCLK-for-PCI-PCIe-bus-always.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0081-clk-ast2600-enable-BCLK-for-PCI-PCIe-bus-always.patch new file mode 100644 index 000000000..22c4d191c --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0081-clk-ast2600-enable-BCLK-for-PCI-PCIe-bus-always.patch @@ -0,0 +1,32 @@ +From ff0b985d3ad004398db3222a40607f1bef433f9b Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo +Date: Tue, 19 Nov 2019 15:12:42 -0800 +Subject: [PATCH] clk: ast2600: enable BCLK for PCI/PCIe bus always + +BCLK for PCI/PCIe bus should be enabled always with having the +CLK_IS_CRITICAL flag otherwise it will be disabled at kernel late +initcall phase as an unused clock, and eventually it causes +unexpected behavior on BMC features that are connected to the host +through PCI/PCIe bus. + +Signed-off-by: Jae Hyun Yoo +--- + drivers/clk/clk-ast2600.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c +index 9191bc3e78ee..8201d65018b9 100644 +--- a/drivers/clk/clk-ast2600.c ++++ b/drivers/clk/clk-ast2600.c +@@ -64,7 +64,7 @@ static const struct aspeed_gate_data aspeed_g6_gates[] = { + [ASPEED_CLK_GATE_GCLK] = { 2, 7, "gclk-gate", NULL, 0 }, /* 2D engine */ + /* vclk parent - dclk/d1clk/hclk/mclk */ + [ASPEED_CLK_GATE_VCLK] = { 3, 6, "vclk-gate", NULL, 0 }, /* Video Capture */ +- [ASPEED_CLK_GATE_BCLK] = { 4, 8, "bclk-gate", "bclk", 0 }, /* PCIe/PCI */ ++ [ASPEED_CLK_GATE_BCLK] = { 4, 8, "bclk-gate", "bclk", CLK_IS_CRITICAL }, /* PCIe/PCI */ + /* From dpll */ + [ASPEED_CLK_GATE_DCLK] = { 5, -1, "dclk-gate", NULL, CLK_IS_CRITICAL }, /* DAC */ + [ASPEED_CLK_GATE_REF0CLK] = { 6, -1, "ref0clk-gate", "clkin", CLK_IS_CRITICAL }, +-- +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 new file mode 100644 index 000000000..b0995992b --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0082-ARM-dts-aspeed-g6-add-USB-virtual-hub-fixup.patch @@ -0,0 +1,53 @@ +From 4594ddeadebe0c818c94671295308c51f00a8e7e 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 88bd02058585..b2549f2a619b 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -253,6 +253,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 new file mode 100644 index 000000000..8093b2bc1 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0083-usb-gadget-aspeed-add-ast2600-compatible-string.patch @@ -0,0 +1,32 @@ +From 7a9aa0e35180a14d352516a92166743a2b063533 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 90b134d5dca9..905e1cfd3d51 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/0084-ARM-dts-aspeed-g6-add-GFX-node.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0084-ARM-dts-aspeed-g6-add-GFX-node.patch new file mode 100644 index 000000000..d3a4a9fdc --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0084-ARM-dts-aspeed-g6-add-GFX-node.patch @@ -0,0 +1,35 @@ +From ad8984556c191b75404fc5608466ee95ccc3b501 Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo +Date: Wed, 20 Nov 2019 15:01:06 -0800 +Subject: [PATCH] ARM: dts: aspeed-g6: add GFX node + +This commit adds GFX node for AST2600 SoC. + +Signed-off-by: Jae Hyun Yoo +--- + arch/arm/boot/dts/aspeed-g6.dtsi | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index b2549f2a619b..34281b14128a 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -311,6 +311,15 @@ + quality = <100>; + }; + ++ gfx: display@1e6e6000 { ++ compatible = "aspeed,ast2600-gfx", "syscon"; ++ reg = <0x1e6e6000 0x1000>; ++ reg-io-width = <4>; ++ clocks = <&syscon ASPEED_CLK_GATE_D1CLK>; ++ status = "disabled"; ++ interrupts = ; ++ }; ++ + adc: adc@1e6e9000 { + compatible = "aspeed,ast2500-adc"; + reg = <0x1e6e9000 0x100>; +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0085-drm-add-AST2600-GFX-support.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0085-drm-add-AST2600-GFX-support.patch new file mode 100644 index 000000000..b936886cf --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0085-drm-add-AST2600-GFX-support.patch @@ -0,0 +1,105 @@ +From 0709e2bab2d763b75683a823c97f4016253ebe6b Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo +Date: Wed, 20 Nov 2019 14:58:24 -0800 +Subject: [PATCH] drm: add AST2600 GFX support + +This commit adds support for AST2600 GFX. + +Signed-off-by: Jae Hyun Yoo +--- + drivers/gpu/drm/aspeed/aspeed_gfx.h | 4 ++++ + drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c | 6 +++--- + drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 18 +++++++++++------- + 3 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx.h b/drivers/gpu/drm/aspeed/aspeed_gfx.h +index a10358bb61ec..eebd72eb1220 100644 +--- a/drivers/gpu/drm/aspeed/aspeed_gfx.h ++++ b/drivers/gpu/drm/aspeed/aspeed_gfx.h +@@ -13,11 +13,15 @@ struct aspeed_gfx { + struct drm_simple_display_pipe pipe; + struct drm_connector connector; + struct drm_fbdev_cma *fbdev; ++ u32 scu_misc_offset; + }; + + int aspeed_gfx_create_pipe(struct drm_device *drm); + int aspeed_gfx_create_output(struct drm_device *drm); + ++#define SCU_MISC_AST2500 0x2c /* SCU Misc of AST2500 */ ++#define SCU_MISC_AST2600 0xc0 /* SCU Misc1 of AST2600 */ ++ + #define CRT_CTRL1 0x60 /* CRT Control I */ + #define CRT_CTRL2 0x64 /* CRT Control II */ + #define CRT_STATUS 0x68 /* CRT Status */ +diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c b/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c +index 15db9e426ec4..2c95c720f34a 100644 +--- a/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c ++++ b/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c +@@ -59,8 +59,8 @@ static void aspeed_gfx_enable_controller(struct aspeed_gfx *priv) + u32 ctrl1 = readl(priv->base + CRT_CTRL1); + u32 ctrl2 = readl(priv->base + CRT_CTRL2); + +- /* SCU2C: set DAC source for display output to Graphics CRT (GFX) */ +- regmap_update_bits(priv->scu, 0x2c, BIT(16), BIT(16)); ++ /* Set DAC source for display output to Graphics CRT (GFX) */ ++ regmap_update_bits(priv->scu, priv->scu_misc_offset, BIT(16), BIT(16)); + + writel(ctrl1 | CRT_CTRL_EN, priv->base + CRT_CTRL1); + writel(ctrl2 | CRT_CTRL_DAC_EN, priv->base + CRT_CTRL2); +@@ -74,7 +74,7 @@ static void aspeed_gfx_disable_controller(struct aspeed_gfx *priv) + writel(ctrl1 & ~CRT_CTRL_EN, priv->base + CRT_CTRL1); + writel(ctrl2 & ~CRT_CTRL_DAC_EN, priv->base + CRT_CTRL2); + +- regmap_update_bits(priv->scu, 0x2c, BIT(16), 0); ++ regmap_update_bits(priv->scu, priv->scu_misc_offset, BIT(16), 0); + } + + static void aspeed_gfx_crtc_mode_set_nofb(struct aspeed_gfx *priv) +diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +index eeb22eccd1fc..aa44e01ac245 100644 +--- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c ++++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +@@ -112,8 +112,14 @@ static int aspeed_gfx_load(struct drm_device *drm) + + priv->scu = syscon_regmap_lookup_by_compatible("aspeed,ast2500-scu"); + if (IS_ERR(priv->scu)) { +- dev_err(&pdev->dev, "failed to find SCU regmap\n"); +- return PTR_ERR(priv->scu); ++ priv->scu = syscon_regmap_lookup_by_compatible("aspeed,ast2600-scu"); ++ if (IS_ERR(priv->scu)) { ++ dev_err(&pdev->dev, "failed to find SCU regmap\n"); ++ return PTR_ERR(priv->scu); ++ } ++ priv->scu_misc_offset = SCU_MISC_AST2600; ++ } else { ++ priv->scu_misc_offset = SCU_MISC_AST2500; + } + + ret = of_reserved_mem_device_init(drm->dev); +@@ -130,12 +136,9 @@ static int aspeed_gfx_load(struct drm_device *drm) + } + + priv->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); +- if (IS_ERR(priv->rst)) { +- dev_err(&pdev->dev, +- "missing or invalid reset controller device tree entry"); +- return PTR_ERR(priv->rst); ++ if (!IS_ERR_OR_NULL(priv->rst)) { ++ reset_control_deassert(priv->rst); + } +- reset_control_deassert(priv->rst); + + priv->clk = devm_clk_get(drm->dev, NULL); + if (IS_ERR(priv->clk)) { +@@ -212,6 +215,7 @@ static struct drm_driver aspeed_gfx_driver = { + + static const struct of_device_id aspeed_gfx_match[] = { + { .compatible = "aspeed,ast2500-gfx" }, ++ { .compatible = "aspeed,ast2600-gfx" }, + { } + }; + +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0086-ADC-linux-driver-for-AST2600.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0086-ADC-linux-driver-for-AST2600.patch new file mode 100644 index 000000000..63b683826 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0086-ADC-linux-driver-for-AST2600.patch @@ -0,0 +1,271 @@ +From 14a4e77c801be8adbfc0726667a8051957e7a7dd Mon Sep 17 00:00:00 2001 +From: Chen Yugang +Date: Tue, 3 Dec 2019 13:41:37 +0800 +Subject: [PATCH] ADC linux driver for AST2600 + +Tested: +it's tested with DC input. + +Signed-off-by: Chen Yugang +--- + arch/arm/boot/dts/aspeed-g6.dtsi | 14 +++++- + drivers/iio/adc/aspeed_adc.c | 99 +++++++++++++++++++++++++++++++++++----- + 2 files changed, 99 insertions(+), 14 deletions(-) + +diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi +index 34281b1..4e8d25f 100644 +--- a/arch/arm/boot/dts/aspeed-g6.dtsi ++++ b/arch/arm/boot/dts/aspeed-g6.dtsi +@@ -320,12 +320,22 @@ + interrupts = ; + }; + +- adc: adc@1e6e9000 { +- compatible = "aspeed,ast2500-adc"; ++ adc0: adc@1e6e9000 { ++ compatible = "aspeed,ast2600-adc"; + reg = <0x1e6e9000 0x100>; + clocks = <&syscon ASPEED_CLK_APB2>; ++ resets = <&syscon ASPEED_RESET_ADC>; + interrupts = ; ++ #io-channel-cells = <1>; ++ status = "disabled"; ++ }; ++ ++ adc1: adc@1e6e9100 { ++ compatible = "aspeed,ast2600-adc"; ++ reg = <0x1e6e9100 0x100>; ++ clocks = <&syscon ASPEED_CLK_APB2>; + resets = <&syscon ASPEED_RESET_ADC>; ++ interrupts = ; + #io-channel-cells = <1>; + status = "disabled"; + }; +diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c +index d3fc39d..1dd5a97 100644 +--- a/drivers/iio/adc/aspeed_adc.c ++++ b/drivers/iio/adc/aspeed_adc.c +@@ -1,8 +1,12 @@ +-// SPDX-License-Identifier: GPL-2.0-only + /* +- * Aspeed AST2400/2500 ADC ++ * Aspeed AST2400/2500/2600 ADC + * + * Copyright (C) 2017 Google, Inc. ++ * Copyright (C) ASPEED Technology Inc. ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * + */ + + #include +@@ -30,6 +34,14 @@ + #define ASPEED_REG_CLOCK_CONTROL 0x0C + #define ASPEED_REG_MAX 0xC0 + ++/* ast2600 */ ++#define REF_VLOTAGE_2500mV 0 ++#define REF_VLOTAGE_1200mV GENMASK(6, 6) ++#define REF_VLOTAGE_1550mV GENMASK(7, 7) ++#define REF_VLOTAGE_900mV GENMASK(7, 6) ++ ++#define ASPEED_AUTOPENSATING BIT(5) ++ + #define ASPEED_OPERATION_MODE_POWER_DOWN (0x0 << 1) + #define ASPEED_OPERATION_MODE_STANDBY (0x1 << 1) + #define ASPEED_OPERATION_MODE_NORMAL (0x7 << 1) +@@ -45,8 +57,10 @@ struct aspeed_adc_model_data { + const char *model_name; + unsigned int min_sampling_rate; // Hz + unsigned int max_sampling_rate; // Hz +- unsigned int vref_voltage; // mV ++ u32 vref_voltage; // mV + bool wait_init_sequence; ++ struct iio_chan_spec const *channels; ++ int num_channels; + }; + + struct aspeed_adc_data { +@@ -56,6 +70,7 @@ struct aspeed_adc_data { + struct clk_hw *clk_prescaler; + struct clk_hw *clk_scaler; + struct reset_control *rst; ++ int cv; + }; + + #define ASPEED_CHAN(_idx, _data_reg_addr) { \ +@@ -87,6 +102,17 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = { + ASPEED_CHAN(15, 0x2E), + }; + ++static const struct iio_chan_spec ast2600_adc_iio_channels[] = { ++ ASPEED_CHAN(0, 0x10), ++ ASPEED_CHAN(1, 0x12), ++ ASPEED_CHAN(2, 0x14), ++ ASPEED_CHAN(3, 0x16), ++ ASPEED_CHAN(4, 0x18), ++ ASPEED_CHAN(5, 0x1A), ++ ASPEED_CHAN(6, 0x1C), ++ ASPEED_CHAN(7, 0x1E), ++}; ++ + static int aspeed_adc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +@@ -175,7 +201,10 @@ static int aspeed_adc_probe(struct platform_device *pdev) + const struct aspeed_adc_model_data *model_data; + struct resource *res; + const char *clk_parent_name; ++ char prescaler_clk_name[32]; ++ char scaler_clk_name[32]; + int ret; ++ u32 eng_ctrl = 0; + u32 adc_engine_control_reg_val; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data)); +@@ -194,19 +223,21 @@ static int aspeed_adc_probe(struct platform_device *pdev) + spin_lock_init(&data->clk_lock); + clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0); + ++ snprintf(prescaler_clk_name, sizeof(prescaler_clk_name), "prescaler-%s", pdev->name); + data->clk_prescaler = clk_hw_register_divider( +- &pdev->dev, "prescaler", clk_parent_name, 0, ++ &pdev->dev, prescaler_clk_name, clk_parent_name, 0, + data->base + ASPEED_REG_CLOCK_CONTROL, + 17, 15, 0, &data->clk_lock); + if (IS_ERR(data->clk_prescaler)) + return PTR_ERR(data->clk_prescaler); + ++ snprintf(scaler_clk_name, sizeof(scaler_clk_name), "scaler-%s", pdev->name); + /* + * Register ADC clock scaler downstream from the prescaler. Allow rate + * setting to adjust the prescaler as well. + */ + data->clk_scaler = clk_hw_register_divider( +- &pdev->dev, "scaler", "prescaler", ++ &pdev->dev, scaler_clk_name, prescaler_clk_name, + CLK_SET_RATE_PARENT, + data->base + ASPEED_REG_CLOCK_CONTROL, + 0, 10, 0, &data->clk_lock); +@@ -215,7 +246,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) + goto scaler_error; + } + +- data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); ++ data->rst = devm_reset_control_get_shared(&pdev->dev, NULL); + if (IS_ERR(data->rst)) { + dev_err(&pdev->dev, + "invalid or missing reset controller device tree entry"); +@@ -225,11 +256,26 @@ static int aspeed_adc_probe(struct platform_device *pdev) + reset_control_deassert(data->rst); + + model_data = of_device_get_match_data(&pdev->dev); ++ if (!of_property_read_u32(pdev->dev.of_node, "ref_voltage", (u32 *)&model_data->vref_voltage)) { ++ if (model_data->vref_voltage == 2500) ++ eng_ctrl = REF_VLOTAGE_2500mV; ++ else if (model_data->vref_voltage == 1200) ++ eng_ctrl = REF_VLOTAGE_1200mV; ++ else if ((model_data->vref_voltage >= 1550) && (model_data->vref_voltage <= 2700)) ++ eng_ctrl = REF_VLOTAGE_1550mV; ++ else if ((model_data->vref_voltage >= 900) && (model_data->vref_voltage <= 1650)) ++ eng_ctrl = REF_VLOTAGE_900mV; ++ else { ++ printk("error ref voltage %d \n", model_data->vref_voltage); ++ eng_ctrl = 0; ++ } ++ } else ++ eng_ctrl = 0; + + if (model_data->wait_init_sequence) { + /* Enable engine in normal mode. */ +- writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE, +- data->base + ASPEED_REG_ENGINE_CONTROL); ++ eng_ctrl |= ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE; ++ writel(eng_ctrl, data->base + ASPEED_REG_ENGINE_CONTROL); + + /* Wait for initial sequence complete. */ + ret = readl_poll_timeout(data->base + ASPEED_REG_ENGINE_CONTROL, +@@ -242,12 +288,26 @@ static int aspeed_adc_probe(struct platform_device *pdev) + goto poll_timeout_error; + } + ++ /* do compensating calculation use ch 0 */ ++ writel(eng_ctrl | ASPEED_OPERATION_MODE_NORMAL | ++ ASPEED_ENGINE_ENABLE | ASPEED_AUTOPENSATING, data->base + ASPEED_REG_ENGINE_CONTROL); ++ ++ writel(eng_ctrl | ASPEED_OPERATION_MODE_NORMAL | BIT(16) | ++ ASPEED_ENGINE_ENABLE | ASPEED_AUTOPENSATING, data->base + ASPEED_REG_ENGINE_CONTROL); ++ mdelay(1); ++ ++ data->cv = 0x200 - (readl(data->base + 0x10) & GENMASK(9, 0)); ++ ++ writel(eng_ctrl | ASPEED_OPERATION_MODE_NORMAL | ++ ASPEED_ENGINE_ENABLE | ASPEED_AUTOPENSATING, data->base + ASPEED_REG_ENGINE_CONTROL); ++ printk(KERN_INFO "aspeed_adc: cv %d \n", data->cv); ++ + /* Start all channels in normal mode. */ + ret = clk_prepare_enable(data->clk_scaler->clk); + if (ret) + goto clk_enable_error; + +- adc_engine_control_reg_val = GENMASK(31, 16) | ++ adc_engine_control_reg_val = eng_ctrl | GENMASK(31, 16) | + ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE; + writel(adc_engine_control_reg_val, + data->base + ASPEED_REG_ENGINE_CONTROL); +@@ -257,8 +317,8 @@ static int aspeed_adc_probe(struct platform_device *pdev) + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &aspeed_adc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; +- indio_dev->channels = aspeed_adc_iio_channels; +- indio_dev->num_channels = ARRAY_SIZE(aspeed_adc_iio_channels); ++ indio_dev->channels = model_data->channels; ++ indio_dev->num_channels = model_data->num_channels; + + ret = iio_device_register(indio_dev); + if (ret) +@@ -301,6 +361,8 @@ static const struct aspeed_adc_model_data ast2400_model_data = { + .vref_voltage = 2500, // mV + .min_sampling_rate = 10000, + .max_sampling_rate = 500000, ++ .channels = aspeed_adc_iio_channels, ++ .num_channels = 16, + }; + + static const struct aspeed_adc_model_data ast2500_model_data = { +@@ -309,11 +371,24 @@ static const struct aspeed_adc_model_data ast2500_model_data = { + .min_sampling_rate = 1, + .max_sampling_rate = 1000000, + .wait_init_sequence = true, ++ .channels = aspeed_adc_iio_channels, ++ .num_channels = 16, ++}; ++ ++static const struct aspeed_adc_model_data ast2600_model_data = { ++ .model_name = "ast2500-adc", ++ .vref_voltage = 1800, /* mV --> can be 1.2v or 2.5 or ext 1.55~2.7v, 0.9v ~1.65v */ ++ .min_sampling_rate = 1, ++ .max_sampling_rate = 1000000, ++ .wait_init_sequence = true, ++ .channels = ast2600_adc_iio_channels, ++ .num_channels = 8, + }; + + static const struct of_device_id aspeed_adc_matches[] = { + { .compatible = "aspeed,ast2400-adc", .data = &ast2400_model_data }, + { .compatible = "aspeed,ast2500-adc", .data = &ast2500_model_data }, ++ { .compatible = "aspeed,ast2600-adc", .data = &ast2600_model_data }, + {}, + }; + MODULE_DEVICE_TABLE(of, aspeed_adc_matches); +@@ -330,5 +405,5 @@ static struct platform_driver aspeed_adc_driver = { + module_platform_driver(aspeed_adc_driver); + + MODULE_AUTHOR("Rick Altherr "); +-MODULE_DESCRIPTION("Aspeed AST2400/2500 ADC Driver"); ++MODULE_DESCRIPTION("Aspeed AST2400/2500/2600 ADC Driver"); + MODULE_LICENSE("GPL"); +-- +2.7.4 + 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 2a4e87d80..714f40bfd 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 @@ -1,6 +1,5 @@ CONFIG_BLK_DEV_RAM=y CONFIG_HWMON=y -CONFIG_SENSORS_ASPEED=y CONFIG_SPI=y CONFIG_SPI_MASTER=y CONFIG_IIO=y @@ -49,6 +48,7 @@ CONFIG_USB_F_HID=y CONFIG_USB_GADGET=y CONFIG_U_SERIAL_CONSOLE=y CONFIG_USB_ASPEED_VHUB=y +CONFIG_USB_MASS_STORAGE=y CONFIG_USB_CONFIGFS=y CONFIG_USB_CONFIGFS_MASS_STORAGE=y CONFIG_USB_CONFIGFS_F_FS=y @@ -72,3 +72,16 @@ CONFIG_CIFS_XATTR=y CONFIG_PSTORE=y CONFIG_PSTORE_ZLIB_COMPRESS=y CONFIG_PSTORE_RAM=y +CONFIG_FSI=n +CONFIG_FSI_MASTER_HUB=n +CONFIG_FSI_MASTER_ASPEED=n +CONFIG_FSI_SCOM=n +CONFIG_FSI_SBEFIFO=n +CONFIG_FSI_OCC=n +CONFIG_ASPEED_P2A_CTRL=n +CONFIG_USB=n +CONFIG_USB_ANNOUNCE_NEW_DEVICES=n +CONFIG_USB_DYNAMIC_MINORS=n +CONFIG_USB_EHCI_HCD=n +CONFIG_USB_EHCI_ROOT_HUB_TT=n +CONFIG_USB_EHCI_HCD_PLATFORM=n 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 085f58182..2ebad4093 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 @@ -8,6 +8,8 @@ do_compile_prepend(){ SRC_URI += " \ file://intel.cfg \ file://0001-arm-dts-add-DTS-for-Intel-ast2500-platforms.patch \ + file://0001-arm-dts-add-DTS-for-Intel-ast2600-platforms.patch \ + file://0001-arm-dts-base-aspeed-g6-dtsi-fixups.patch \ file://0002-Enable-pass-through-on-GPIOE1-and-GPIOE3-free.patch \ file://0003-Enable-GPIOE0-and-GPIOE2-pass-through-by-default.patch \ file://0006-Allow-monitoring-of-power-control-input-GPIOs.patch \ @@ -44,7 +46,6 @@ SRC_URI += " \ file://0055-Documentation-jtag-Add-ABI-documentation.patch \ file://0056-Documentation-jtag-Add-JTAG-core-driver-ioctl-number.patch \ file://0057-drivers-jtag-Add-JTAG-core-driver-Maintainers.patch \ - file://0060-i2c-aspeed-fix-master-pending-state-handling.patch \ file://0061-i2c-aspeed-add-buffer-mode-transfer-support.patch \ file://0062-i2c-aspeed-add-DMA-mode-transfer-support.patch \ file://0063-i2c-aspeed-add-general-call-support.patch \ @@ -57,7 +58,17 @@ SRC_URI += " \ 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://0079-usb-gadget-aspeed-backport-aspeed-vhub-bug-fixes.patch \ + file://0080-i2c-aspeed-filter-garbage-interrupts-out.patch \ + file://0081-clk-ast2600-enable-BCLK-for-PCI-PCIe-bus-always.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 \ " SRC_URI += "${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', 'file://0005-128MB-flashmap-for-PFR.patch', '', d)}" -- cgit v1.2.3