Support is added for 5 new Qualcomm SoCs:

* QCM2290 and SM6115 are low and mid range SoCs used on the RB1 and RB2
  respectively. SM6115 is also used in some mid-range smartphones/tablets.
  Initial support includes buttons and USB (host and gadget).
* SM8250 is a flagship SoC from 2020 used on the RB5, as well as many flagship
  smartphones. The board can boot to a U-Boot prompt, but is missing regulators
  necessary for USB support.
* SM8550, and SM8650 are flagship mobile SoCs from 2023 and 2024
  respectively. Found on many high end smartphones.

In addition:

* Support is added for the Schneider HMIBSC board.
* mach-snapdragon switches to OF_UPSTREAM
* IPQ40xx gets several regressions fixed and some overall cleanup.
* The MSM serial driver gains the ability to generate the bit-clock
  automatically, no longer relying on a custom DT property.
* The Qualcomm SMMU driver gets a generic compatible (so per-SoC compatibles
  don't need to be added).
* Support for the GENI I2C controller is added.
* The qcom SPMI driver has SPMI v5 support fixed, and v7 support added.
* The qcom sdhci driver gets some fixes for SDCC v5 support.
* SDM845 gains sdcard support
* Support is added for the Synopsys eUSB2 PHY driver (used on SM8550 and SM8650)
* SYS_INIT_SP_BSS_OFFSET is set to 1.5M to give us more space for FDTs.
* RB2 gets a work-around to fix the USB dr_mode property before booting Linux.
This commit is contained in:
Tom Rini
2024-04-23 08:33:37 -06:00
74 changed files with 4403 additions and 19118 deletions

View File

@@ -603,11 +603,9 @@ ARM SNAPDRAGON
M: Caleb Connolly <caleb.connolly@linaro.org>
M: Neil Armstrong <neil.armstrong@linaro.org>
R: Sumit Garg <sumit.garg@linaro.org>
L: u-boot-qcom@groups.io
S: Maintained
F: arch/arm/dts/msm8*.dtsi
F: arch/arm/dts/pm8???.dtsi
F: arch/arm/dts/pms405.dtsi
F: arch/arm/dts/sdm845.dtsi
T: git https://source.denx.de/u-boot/custodians/u-boot-snapdragon.git
F: drivers/*/*/pm8???-*
F: drivers/gpio/msm_gpio.c
F: drivers/mmc/msm_sdhci.c

View File

@@ -762,10 +762,8 @@ config ARCH_IPQ40XX
select DM_SERIAL
select DM_RESET
select GPIO_EXTRA_HEADER
select MSM_SMEM
select PINCTRL
select CLK
select SMEM
select OF_CONTROL
select CLK_QCOM_IPQ4019
select PINCTRL_QCOM_IPQ4019
@@ -1089,7 +1087,8 @@ config ARCH_SNAPDRAGON
select BOARD_LATE_INIT
select OF_BOARD
select SAVE_PREV_BL_FDT_ADDR
select LINUX_KERNEL_IMAGE_HEADER
select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK
imply OF_UPSTREAM
imply CMD_DM
config ARCH_SOCFPGA

View File

@@ -572,12 +572,6 @@ dtb-$(CONFIG_TARGET_SL28) += fsl-ls1028a-kontron-sl28.dtb \
dtb-$(CONFIG_TARGET_TEN64) += fsl-ls1088a-ten64.dtb
dtb-$(CONFIG_ARCH_SNAPDRAGON) += apq8016-sbc.dtb \
apq8096-db820c.dtb \
sdm845-db845c.dtb \
sdm845-samsung-starqltechn.dtb \
qcs404-evb-4000.dtb
dtb-$(CONFIG_TARGET_STEMMY) += ste-ux500-samsung-stemmy.dtb
dtb-$(CONFIG_STM32F4) += stm32f429-disco.dtb \

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
* Copyright (c) 2024, Linaro Ltd.
*/
/dts-v1/;
@@ -14,50 +15,25 @@
#include <dt-bindings/sound/apq8016-lpass.h>
/ {
model = "Qualcomm Technologies, Inc. APQ 8016 SBC";
compatible = "qcom,apq8016-sbc", "qcom,apq8016";
model = "Schneider Electric HMIBSC Board";
compatible = "schneider,apq8016-hmibsc", "qcom,apq8016";
aliases {
mmc0 = &sdhc_1; /* eMMC */
mmc1 = &sdhc_2; /* SD card */
serial0 = &blsp_uart2;
serial1 = &blsp_uart1;
usid0 = &pm8916_0;
i2c0 = &blsp_i2c2;
i2c1 = &blsp_i2c6;
i2c3 = &blsp_i2c4;
i2c4 = &blsp_i2c3;
mmc0 = &sdhc_1; /* eMMC */
mmc1 = &sdhc_2; /* SD card */
serial0 = &blsp_uart1;
serial1 = &blsp_uart2;
spi0 = &blsp_spi5;
spi1 = &blsp_spi3;
usid0 = &pm8916_0;
};
chosen {
stdout-path = "serial0";
};
reserved-memory {
ramoops@bff00000 {
compatible = "ramoops";
reg = <0x0 0xbff00000 0x0 0x100000>;
record-size = <0x20000>;
console-size = <0x20000>;
ftrace-size = <0x20000>;
};
};
usb2513 {
compatible = "smsc,usb3503";
reset-gpios = <&pm8916_gpios 3 GPIO_ACTIVE_LOW>;
initial-mode = <1>;
};
usb_id: usb-id {
compatible = "linux,extcon-usb-gpio";
id-gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usb_id_default>;
};
hdmi-out {
compatible = "hdmi-connector";
type = "a";
@@ -72,9 +48,8 @@
gpio-keys {
compatible = "gpio-keys";
autorepeat;
pinctrl-names = "default";
pinctrl-0 = <&msm_key_volp_n_default>;
pinctrl-names = "default";
button {
label = "Volume Up";
@@ -84,51 +59,11 @@
};
leds {
pinctrl-names = "default";
pinctrl-0 = <&tlmm_leds>,
<&pm8916_gpios_leds>,
<&pm8916_mpps_leds>;
compatible = "gpio-leds";
pinctrl-0 = <&pm8916_mpps_leds>;
pinctrl-names = "default";
led@1 {
label = "apq8016-sbc:green:user1";
function = LED_FUNCTION_HEARTBEAT;
color = <LED_COLOR_ID_GREEN>;
gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
default-state = "off";
};
led@2 {
label = "apq8016-sbc:green:user2";
function = LED_FUNCTION_DISK_ACTIVITY;
color = <LED_COLOR_ID_GREEN>;
gpios = <&tlmm 120 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "mmc0";
default-state = "off";
};
led@3 {
label = "apq8016-sbc:green:user3";
function = LED_FUNCTION_DISK_ACTIVITY;
color = <LED_COLOR_ID_GREEN>;
gpios = <&pm8916_gpios 1 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "mmc1";
default-state = "off";
};
led@4 {
label = "apq8016-sbc:green:user4";
color = <LED_COLOR_ID_GREEN>;
gpios = <&pm8916_gpios 2 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "none";
panic-indicator;
default-state = "off";
};
led@5 {
label = "apq8016-sbc:yellow:wlan";
led-1 {
function = LED_FUNCTION_WLAN;
color = <LED_COLOR_ID_YELLOW>;
gpios = <&pm8916_mpps 2 GPIO_ACTIVE_HIGH>;
@@ -136,8 +71,7 @@
default-state = "off";
};
led@6 {
label = "apq8016-sbc:blue:bt";
led-2 {
function = LED_FUNCTION_BLUETOOTH;
color = <LED_COLOR_ID_BLUE>;
gpios = <&pm8916_mpps 3 GPIO_ACTIVE_HIGH>;
@@ -145,30 +79,56 @@
default-state = "off";
};
};
memory@80000000 {
reg = <0 0x80000000 0 0x40000000>;
};
&blsp_i2c2 {
/* On Low speed expansion: LS-I2C0 */
reserved-memory {
ramoops@bff00000 {
compatible = "ramoops";
reg = <0x0 0xbff00000 0x0 0x100000>;
record-size = <0x20000>;
console-size = <0x20000>;
ftrace-size = <0x20000>;
ecc-size = <16>;
};
};
usb-hub {
compatible = "smsc,usb3503";
reset-gpios = <&pm8916_gpios 1 GPIO_ACTIVE_LOW>;
initial-mode = <1>;
};
usb_id: usb-id {
compatible = "linux,extcon-usb-gpio";
id-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>;
pinctrl-0 = <&usb_id_default>;
pinctrl-names = "default";
};
};
&blsp_i2c3 {
status = "okay";
eeprom@50 {
compatible = "atmel,24c32";
reg = <0x50>;
};
};
&blsp_i2c4 {
/* On High speed expansion: HS-I2C2 */
status = "okay";
adv_bridge: bridge@39 {
status = "okay";
compatible = "adi,adv7533";
reg = <0x39>;
interrupt-parent = <&tlmm>;
interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
interrupts-extended = <&tlmm 31 IRQ_TYPE_EDGE_FALLING>;
adi,dsi-lanes = <4>;
clocks = <&rpmcc RPM_SMD_BB_CLK2>;
clock-names = "cec";
pd-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
avdd-supply = <&pm8916_l6>;
@@ -178,10 +138,10 @@
v1p2-supply = <&pm8916_l6>;
v3p3-supply = <&pm8916_l17>;
pinctrl-names = "default","sleep";
pinctrl-0 = <&adv7533_int_active &adv7533_switch_active>;
pinctrl-1 = <&adv7533_int_suspend &adv7533_switch_suspend>;
#sound-dai-cells = <1>;
pinctrl-names = "default","sleep";
#sound-dai-cells = <0>;
ports {
#address-cells = <1>;
@@ -205,35 +165,37 @@
};
&blsp_i2c6 {
/* On Low speed expansion: LS-I2C1 */
status = "okay";
rtc@30 {
compatible = "sii,s35390a";
reg = <0x30>;
};
&blsp_spi3 {
/* On High speed expansion: HS-SPI1 */
status = "okay";
eeprom@50 {
compatible = "atmel,24c256";
reg = <0x50>;
};
};
&blsp_spi5 {
/* On Low speed expansion: LS-SPI0 */
cs-gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
status = "okay";
tpm@0 {
compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
reg = <0>;
spi-max-frequency = <500000>;
};
};
&blsp_uart1 {
label = "UART0";
status = "okay";
label = "LS-UART0";
};
&blsp_uart2 {
status = "okay";
label = "LS-UART1";
};
&camss {
status = "okay";
};
&gpu {
label = "UART1";
status = "okay";
};
@@ -241,14 +203,6 @@
status = "okay";
};
&lpass_codec {
status = "okay";
};
&mba_mem {
status = "okay";
};
&mdss {
status = "okay";
};
@@ -258,51 +212,70 @@
remote-endpoint = <&adv7533_in>;
};
&mpss {
status = "okay";
firmware-name = "qcom/apq8016/mba.mbn", "qcom/apq8016/modem.mbn";
};
&mpss_mem {
status = "okay";
reg = <0x0 0x86800000 0x0 0x2b00000>;
};
&pm8916_codec {
status = "okay";
qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
status = "okay";
};
&pm8916_gpios {
gpio-line-names =
"USB_HUB_RESET_N_PM",
"USB_SW_SEL_PM",
"NC",
"NC";
usb_hub_reset_pm: usb-hub-reset-pm-state {
pins = "gpio1";
function = PMIC_GPIO_FUNC_NORMAL;
input-disable;
output-high;
};
usb_hub_reset_pm_device: usb-hub-reset-pm-device-state {
pins = "gpio1";
function = PMIC_GPIO_FUNC_NORMAL;
input-disable;
output-low;
};
usb_sw_sel_pm: usb-sw-sel-pm-state {
pins = "gpio2";
function = PMIC_GPIO_FUNC_NORMAL;
power-source = <PM8916_GPIO_VPH>;
input-disable;
output-high;
};
usb_sw_sel_pm_device: usb-sw-sel-pm-device-state {
pins = "gpio2";
function = PMIC_GPIO_FUNC_NORMAL;
power-source = <PM8916_GPIO_VPH>;
input-disable;
output-low;
};
};
&pm8916_mpps {
gpio-line-names =
"NC",
"WLAN_LED_CTRL",
"BT_LED_CTRL",
"NC";
pm8916_mpps_leds: pm8916-mpps-state {
pins = "mpp2", "mpp3";
function = "digital";
output-low;
};
};
&pm8916_resin {
linux,code = <KEY_POWER>;
status = "okay";
linux,code = <KEY_VOLUMEDOWN>;
};
&pm8916_rpm_regulators {
/*
* The 96Boards specification expects a 1.8V power rail on the low-speed
* expansion connector that is able to provide at least 0.18W / 100 mA.
* L15/L16 are connected in parallel to provide 55 mA each. A minimum load
* must be specified to ensure the regulators are not put in LPM where they
* would only provide 5 mA.
*/
pm8916_l15: l15 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-system-load = <50000>;
regulator-allow-set-load;
regulator-always-on;
};
pm8916_l16: l16 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-system-load = <50000>;
regulator-allow-set-load;
regulator-always-on;
};
pm8916_l17: l17 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
@@ -314,25 +287,22 @@
};
&sdhc_2 {
status = "okay";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&sdc2_default &sdc2_cd_default>;
pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>;
pinctrl-names = "default", "sleep";
cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
status = "okay";
};
&sound {
status = "okay";
pinctrl-0 = <&cdc_pdm_default &sec_mi2s_default>;
pinctrl-1 = <&cdc_pdm_sleep &sec_mi2s_sleep>;
pinctrl-names = "default", "sleep";
model = "DB410c";
model = "HMIBSC";
audio-routing =
"AMIC2", "MIC BIAS Internal2",
"AMIC3", "MIC BIAS External1";
status = "okay";
quaternary-dai-link {
link-name = "ADV7533";
@@ -365,30 +335,106 @@
};
};
&usb {
status = "okay";
extcon = <&usb_id>, <&usb_id>;
&tlmm {
pinctrl-0 = <&uart1_mux0_rs232_high &uart1_mux1_rs232_low>;
pinctrl-names = "default";
pinctrl-names = "default", "device";
adv7533_int_active: adv533-int-active-state {
pins = "gpio31";
function = "gpio";
drive-strength = <16>;
bias-disable;
};
adv7533_int_suspend: adv7533-int-suspend-state {
pins = "gpio31";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
adv7533_switch_active: adv7533-switch-active-state {
pins = "gpio32";
function = "gpio";
drive-strength = <16>;
bias-disable;
};
adv7533_switch_suspend: adv7533-switch-suspend-state {
pins = "gpio32";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
msm_key_volp_n_default: msm-key-volp-n-default-state {
pins = "gpio107";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
sdc2_cd_default: sdc2-cd-default-state {
pins = "gpio38";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
/*
* UART1 being the debug console supports various modes of
* operation (RS-232/485/422) controlled via GPIOs configured
* mux as follows:
*
* gpio100 gpio99 UART mode
* 0 0 loopback
* 0 1 RS-232
* 1 0 RS-485
* 1 1 RS-422
*
* The default mode configured here is RS-232 mode.
*/
uart1_mux0_rs232_high: uart1-mux0-rs232-state {
bootph-all;
pins = "gpio99";
function = "gpio";
drive-strength = <16>;
bias-disable;
output-high;
};
uart1_mux1_rs232_low: uart1-mux1-rs232-state {
bootph-all;
pins = "gpio100";
function = "gpio";
drive-strength = <16>;
bias-disable;
output-low;
};
usb_id_default: usb-id-default-state {
pins = "gpio110";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
&usb {
extcon = <&usb_id>, <&usb_id>;
pinctrl-0 = <&usb_sw_sel_pm &usb_hub_reset_pm>;
pinctrl-1 = <&usb_sw_sel_pm_device &usb_hub_reset_pm_device>;
pinctrl-names = "default", "device";
status = "okay";
};
&usb_hs_phy {
extcon = <&usb_id>;
};
&venus {
status = "okay";
};
&venus_mem {
status = "okay";
};
&wcnss {
status = "okay";
firmware-name = "qcom/apq8016/wcnss.mbn";
status = "okay";
};
&wcnss_ctrl {
@@ -403,6 +449,24 @@
status = "okay";
};
/* PINCTRL - additions to nodes defined in msm8916.dtsi */
/*
* 2mA drive strength is not enough when connecting multiple
* I2C devices with different pull up resistors.
*/
&blsp_i2c4_default {
drive-strength = <16>;
};
&blsp_i2c6_default {
drive-strength = <16>;
};
&blsp_uart1_default {
bootph-all;
};
/* Enable CoreSight */
&cti0 { status = "okay"; };
&cti1 { status = "okay"; };
@@ -425,305 +489,3 @@
&replicator { status = "okay"; };
&stm { status = "okay"; };
&tpiu { status = "okay"; };
/*
* 2mA drive strength is not enough when connecting multiple
* I2C devices with different pull up resistors.
*/
&blsp_i2c2_default {
drive-strength = <16>;
};
&blsp_i2c4_default {
drive-strength = <16>;
};
&blsp_i2c6_default {
drive-strength = <16>;
};
/*
* GPIO name legend: proper name = the GPIO line is used as GPIO
* NC = not connected (pin out but not routed from the chip to
* anything the board)
* "[PER]" = pin is muxed for [peripheral] (not GPIO)
* LSEC = Low Speed External Connector
* HSEC = High Speed External Connector
*
* Line names are taken from the schematic "DragonBoard410c"
* dated monday, august 31, 2015. Page 5 in particular.
*
* For the lines routed to the external connectors the
* lines are named after the 96Boards CE Specification 1.0,
* Appendix "Expansion Connector Signal Description".
*
* When the 96Board naming of a line and the schematic name of
* the same line are in conflict, the 96Board specification
* takes precedence, which means that the external UART on the
* LSEC is named UART0 while the schematic and SoC names this
* UART3. This is only for the informational lines i.e. "[FOO]",
* the GPIO named lines "GPIO-A" thru "GPIO-L" are the only
* ones actually used for GPIO.
*/
&tlmm {
gpio-line-names =
"[UART0_TX]", /* GPIO_0, LSEC pin 5 */
"[UART0_RX]", /* GPIO_1, LSEC pin 7 */
"[UART0_CTS_N]", /* GPIO_2, LSEC pin 3 */
"[UART0_RTS_N]", /* GPIO_3, LSEC pin 9 */
"[UART1_TX]", /* GPIO_4, LSEC pin 11 */
"[UART1_RX]", /* GPIO_5, LSEC pin 13 */
"[I2C0_SDA]", /* GPIO_8, LSEC pin 17 */
"[I2C0_SCL]", /* GPIO_7, LSEC pin 15 */
"[SPI1_DOUT]", /* SPI1_MOSI, HSEC pin 1 */
"[SPI1_DIN]", /* SPI1_MISO, HSEC pin 11 */
"[SPI1_CS]", /* SPI1_CS_N, HSEC pin 7 */
"[SPI1_SCLK]", /* SPI1_CLK, HSEC pin 9 */
"GPIO-B", /* LS_EXP_GPIO_B, LSEC pin 24 */
"GPIO-C", /* LS_EXP_GPIO_C, LSEC pin 25 */
"[I2C3_SDA]", /* HSEC pin 38 */
"[I2C3_SCL]", /* HSEC pin 36 */
"[SPI0_MOSI]", /* LSEC pin 14 */
"[SPI0_MISO]", /* LSEC pin 10 */
"[SPI0_CS_N]", /* LSEC pin 12 */
"[SPI0_CLK]", /* LSEC pin 8 */
"HDMI_HPD_N", /* GPIO 20 */
"USR_LED_1_CTRL",
"[I2C1_SDA]", /* GPIO_22, LSEC pin 21 */
"[I2C1_SCL]", /* GPIO_23, LSEC pin 19 */
"GPIO-G", /* LS_EXP_GPIO_G, LSEC pin 29 */
"GPIO-H", /* LS_EXP_GPIO_H, LSEC pin 30 */
"[CSI0_MCLK]", /* HSEC pin 15 */
"[CSI1_MCLK]", /* HSEC pin 17 */
"GPIO-K", /* LS_EXP_GPIO_K, LSEC pin 33 */
"[I2C2_SDA]", /* HSEC pin 34 */
"[I2C2_SCL]", /* HSEC pin 32 */
"DSI2HDMI_INT_N",
"DSI_SW_SEL_APQ",
"GPIO-L", /* LS_EXP_GPIO_L, LSEC pin 34 */
"GPIO-J", /* LS_EXP_GPIO_J, LSEC pin 32 */
"GPIO-I", /* LS_EXP_GPIO_I, LSEC pin 31 */
"GPIO-A", /* LS_EXP_GPIO_A, LSEC pin 23 */
"FORCED_USB_BOOT",
"SD_CARD_DET_N",
"[WCSS_BT_SSBI]",
"[WCSS_WLAN_DATA_2]", /* GPIO 40 */
"[WCSS_WLAN_DATA_1]",
"[WCSS_WLAN_DATA_0]",
"[WCSS_WLAN_SET]",
"[WCSS_WLAN_CLK]",
"[WCSS_FM_SSBI]",
"[WCSS_FM_SDI]",
"[WCSS_BT_DAT_CTL]",
"[WCSS_BT_DAT_STB]",
"NC",
"NC", /* GPIO 50 */
"NC",
"NC",
"NC",
"NC",
"NC",
"NC",
"NC",
"NC",
"NC",
"NC", /* GPIO 60 */
"NC",
"NC",
"[CDC_PDM0_CLK]",
"[CDC_PDM0_SYNC]",
"[CDC_PDM0_TX0]",
"[CDC_PDM0_RX0]",
"[CDC_PDM0_RX1]",
"[CDC_PDM0_RX2]",
"GPIO-D", /* LS_EXP_GPIO_D, LSEC pin 26 */
"NC", /* GPIO 70 */
"NC",
"NC",
"NC",
"NC", /* GPIO 74 */
"NC",
"NC",
"NC",
"NC",
"NC",
"BOOT_CONFIG_0", /* GPIO 80 */
"BOOT_CONFIG_1",
"BOOT_CONFIG_2",
"BOOT_CONFIG_3",
"NC",
"NC",
"BOOT_CONFIG_5",
"NC",
"NC",
"NC",
"NC", /* GPIO 90 */
"NC",
"NC",
"NC",
"NC",
"NC",
"NC",
"NC",
"NC",
"NC",
"NC", /* GPIO 100 */
"NC",
"NC",
"NC",
"SSBI_GPS",
"NC",
"NC",
"KEY_VOLP_N",
"NC",
"NC",
"[LS_EXP_MI2S_WS]", /* GPIO 110 */
"NC",
"NC",
"[LS_EXP_MI2S_SCK]",
"[LS_EXP_MI2S_DATA0]",
"GPIO-E", /* LS_EXP_GPIO_E, LSEC pin 27 */
"NC",
"[DSI2HDMI_MI2S_WS]",
"[DSI2HDMI_MI2S_SCK]",
"[DSI2HDMI_MI2S_DATA0]",
"USR_LED_2_CTRL", /* GPIO 120 */
"SB_HS_ID";
sdc2_cd_default: sdc2-cd-default-state {
pins = "gpio38";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
tlmm_leds: tlmm-leds-state {
pins = "gpio21", "gpio120";
function = "gpio";
output-low;
};
usb_id_default: usb-id-default-state {
pins = "gpio121";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
adv7533_int_active: adv533-int-active-state {
pins = "gpio31";
function = "gpio";
drive-strength = <16>;
bias-disable;
};
adv7533_int_suspend: adv7533-int-suspend-state {
pins = "gpio31";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
adv7533_switch_active: adv7533-switch-active-state {
pins = "gpio32";
function = "gpio";
drive-strength = <16>;
bias-disable;
};
adv7533_switch_suspend: adv7533-switch-suspend-state {
pins = "gpio32";
function = "gpio";
drive-strength = <2>;
bias-disable;
};
msm_key_volp_n_default: msm-key-volp-n-default-state {
pins = "gpio107";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
&pm8916_gpios {
gpio-line-names =
"USR_LED_3_CTRL",
"USR_LED_4_CTRL",
"USB_HUB_RESET_N_PM",
"USB_SW_SEL_PM";
usb_hub_reset_pm: usb-hub-reset-pm-state {
pins = "gpio3";
function = PMIC_GPIO_FUNC_NORMAL;
input-disable;
output-high;
};
usb_hub_reset_pm_device: usb-hub-reset-pm-device-state {
pins = "gpio3";
function = PMIC_GPIO_FUNC_NORMAL;
output-low;
};
usb_sw_sel_pm: usb-sw-sel-pm-state {
pins = "gpio4";
function = PMIC_GPIO_FUNC_NORMAL;
power-source = <PM8916_GPIO_VPH>;
input-disable;
output-high;
};
usb_sw_sel_pm_device: usb-sw-sel-pm-device-state {
pins = "gpio4";
function = PMIC_GPIO_FUNC_NORMAL;
power-source = <PM8916_GPIO_VPH>;
input-disable;
output-low;
};
pm8916_gpios_leds: pm8916-gpios-leds-state {
pins = "gpio1", "gpio2";
function = PMIC_GPIO_FUNC_NORMAL;
output-low;
};
};
&pm8916_mpps {
gpio-line-names =
"VDD_PX_BIAS",
"WLAN_LED_CTRL",
"BT_LED_CTRL",
"GPIO-F"; /* LS_EXP_GPIO_F, LSEC pin 28 */
pinctrl-names = "default";
pinctrl-0 = <&ls_exp_gpio_f>;
ls_exp_gpio_f: pm8916-mpp4-state {
pins = "mpp4";
function = "digital";
output-low;
power-source = <PM8916_MPP_L5>; /* 1.8V */
};
pm8916_mpps_leds: pm8916-mpps-state {
pins = "mpp2", "mpp3";
function = "digital";
output-low;
};
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,157 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* msm8916-pm8916.dtsi describes common properties (e.g. regulator connections)
* that apply to most devices that make use of the MSM8916 SoC and PM8916 PMIC.
* Many regulators have a fixed purpose in the original reference design and
* were rarely re-used for different purposes. Devices that deviate from the
* typical reference design should not make use of this include and instead add
* the necessary properties in the board-specific device tree.
*/
#include "msm8916.dtsi"
#include "pm8916.dtsi"
&camss {
vdda-supply = <&pm8916_l2>;
};
&mdss_dsi0 {
vdda-supply = <&pm8916_l2>;
vddio-supply = <&pm8916_l6>;
};
&mdss_dsi0_phy {
vddio-supply = <&pm8916_l6>;
};
&mpss {
pll-supply = <&pm8916_l7>;
};
&pm8916_codec {
vdd-cdc-io-supply = <&pm8916_l5>;
vdd-cdc-tx-rx-cx-supply = <&pm8916_l5>;
vdd-micbias-supply = <&pm8916_l13>;
};
&sdhc_1 {
vmmc-supply = <&pm8916_l8>;
vqmmc-supply = <&pm8916_l5>;
};
&sdhc_2 {
vmmc-supply = <&pm8916_l11>;
vqmmc-supply = <&pm8916_l12>;
};
&usb_hs_phy {
v1p8-supply = <&pm8916_l7>;
v3p3-supply = <&pm8916_l13>;
};
&wcnss {
vddpx-supply = <&pm8916_l7>;
};
&wcnss_iris {
vddxo-supply = <&pm8916_l7>;
vddrfa-supply = <&pm8916_s3>;
vddpa-supply = <&pm8916_l9>;
vdddig-supply = <&pm8916_l5>;
};
&rpm_requests {
pm8916_rpm_regulators: regulators {
compatible = "qcom,rpm-pm8916-regulators";
vdd_l1_l2_l3-supply = <&pm8916_s3>;
vdd_l4_l5_l6-supply = <&pm8916_s4>;
vdd_l7-supply = <&pm8916_s4>;
/* pm8916_s1 is managed by rpmpd (MSM8916_VDDCX) */
pm8916_s3: s3 {
regulator-min-microvolt = <1250000>;
regulator-max-microvolt = <1350000>;
regulator-always-on; /* Needed for L2 */
};
pm8916_s4: s4 {
regulator-min-microvolt = <1850000>;
regulator-max-microvolt = <2150000>;
regulator-always-on; /* Needed for L5/L7 */
};
/*
* Some of the regulators are unused or managed by another
* processor (e.g. the modem). We should still define nodes for
* them to ensure the vote from the application processor can be
* dropped in case the regulators are already on during boot.
*
* The labels for these nodes are omitted on purpose because
* boards should configure a proper voltage before using them.
*/
l1 {};
pm8916_l2: l2 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on; /* Needed for LPDDR RAM */
};
/* pm8916_l3 is managed by rpmpd (MSM8916_VDDMX) */
l4 {};
pm8916_l5: l5 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on; /* Needed for most digital I/O */
};
pm8916_l6: l6 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
pm8916_l7: l7 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on; /* Needed for CPU PLL */
};
pm8916_l8: l8 {
regulator-min-microvolt = <2900000>;
regulator-max-microvolt = <2900000>;
};
pm8916_l9: l9 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
l10 {};
pm8916_l11: l11 {
regulator-min-microvolt = <2950000>;
regulator-max-microvolt = <2950000>;
regulator-allow-set-load;
regulator-system-load = <200000>;
};
pm8916_l12: l12 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2950000>;
};
pm8916_l13: l13 {
regulator-min-microvolt = <3075000>;
regulator-max-microvolt = <3075000>;
};
l14 {};
l15 {};
l16 {};
l17 {};
l18 {};
};
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,178 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/iio/qcom,spmi-vadc.h>
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/spmi/spmi.h>
&spmi_bus {
pm8916_0: pmic@0 {
compatible = "qcom,pm8916", "qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
pon@800 {
compatible = "qcom,pm8916-pon";
reg = <0x800>;
mode-bootloader = <0x2>;
mode-recovery = <0x1>;
pwrkey {
compatible = "qcom,pm8941-pwrkey";
interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
debounce = <15625>;
bias-pull-up;
linux,code = <KEY_POWER>;
};
pm8916_resin: resin {
compatible = "qcom,pm8941-resin";
interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
debounce = <15625>;
bias-pull-up;
status = "disabled";
};
watchdog {
compatible = "qcom,pm8916-wdt";
interrupts = <0x0 0x8 6 IRQ_TYPE_EDGE_RISING>;
timeout-sec = <60>;
};
};
pm8916_usbin: usb-detect@1300 {
compatible = "qcom,pm8941-misc";
reg = <0x1300>;
interrupts = <0x0 0x13 1 IRQ_TYPE_EDGE_BOTH>;
interrupt-names = "usb_vbus";
status = "disabled";
};
pm8916_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>;
interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>;
io-channels = <&pm8916_vadc VADC_DIE_TEMP>;
io-channel-names = "thermal";
#thermal-sensor-cells = <0>;
};
pm8916_vadc: adc@3100 {
compatible = "qcom,spmi-vadc";
reg = <0x3100>;
interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
#address-cells = <1>;
#size-cells = <0>;
#io-channel-cells = <1>;
channel@0 {
reg = <VADC_USBIN>;
qcom,pre-scaling = <1 10>;
};
channel@7 {
reg = <VADC_VSYS>;
qcom,pre-scaling = <1 3>;
};
channel@8 {
reg = <VADC_DIE_TEMP>;
};
channel@9 {
reg = <VADC_REF_625MV>;
};
channel@a {
reg = <VADC_REF_1250MV>;
};
channel@e {
reg = <VADC_GND_REF>;
};
channel@f {
reg = <VADC_VDD_VADC>;
};
};
rtc@6000 {
compatible = "qcom,pm8941-rtc";
reg = <0x6000>, <0x6100>;
reg-names = "rtc", "alarm";
interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
};
pm8916_mpps: mpps@a000 {
compatible = "qcom,pm8916-mpp", "qcom,spmi-mpp";
reg = <0xa000>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pm8916_mpps 0 0 4>;
interrupt-controller;
#interrupt-cells = <2>;
};
pm8916_gpios: gpio@c000 {
compatible = "qcom,pm8916-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
gpio-controller;
gpio-ranges = <&pm8916_gpios 0 0 4>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
};
pm8916_1: pmic@1 {
compatible = "qcom,pm8916", "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
pm8916_pwm: pwm {
compatible = "qcom,pm8916-pwm";
#pwm-cells = <2>;
status = "disabled";
};
pm8916_vib: vibrator@c000 {
compatible = "qcom,pm8916-vib";
reg = <0xc000>;
status = "disabled";
};
pm8916_codec: audio-codec@f000 {
compatible = "qcom,pm8916-wcd-analog-codec";
reg = <0xf000>;
interrupt-parent = <&spmi_bus>;
interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
<0x1 0xf0 0x1 IRQ_TYPE_NONE>,
<0x1 0xf0 0x2 IRQ_TYPE_NONE>,
<0x1 0xf0 0x3 IRQ_TYPE_NONE>,
<0x1 0xf0 0x4 IRQ_TYPE_NONE>,
<0x1 0xf0 0x5 IRQ_TYPE_NONE>,
<0x1 0xf0 0x6 IRQ_TYPE_NONE>,
<0x1 0xf0 0x7 IRQ_TYPE_NONE>,
<0x1 0xf1 0x0 IRQ_TYPE_NONE>,
<0x1 0xf1 0x1 IRQ_TYPE_NONE>,
<0x1 0xf1 0x2 IRQ_TYPE_NONE>,
<0x1 0xf1 0x3 IRQ_TYPE_NONE>,
<0x1 0xf1 0x4 IRQ_TYPE_NONE>,
<0x1 0xf1 0x5 IRQ_TYPE_NONE>;
interrupt-names = "cdc_spk_cnp_int",
"cdc_spk_clip_int",
"cdc_spk_ocp_int",
"mbhc_ins_rem_det1",
"mbhc_but_rel_det",
"mbhc_but_press_det",
"mbhc_ins_rem_det",
"mbhc_switch_int",
"cdc_ear_ocp_int",
"cdc_hphr_ocp_int",
"cdc_hphl_ocp_det",
"cdc_ear_cnp_int",
"cdc_hphr_cnp_int",
"cdc_hphl_cnp_int";
#sound-dai-cells = <1>;
status = "disabled";
};
};
};

View File

@@ -1,152 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/iio/qcom,spmi-vadc.h>
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/spmi/spmi.h>
/ {
thermal-zones {
pm8994-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
thermal-sensors = <&pm8994_temp>;
trips {
pm8994_alert0: pm8994-alert0 {
temperature = <95000>;
hysteresis = <2000>;
type = "passive";
};
pm8994_crit: pm8994-crit {
temperature = <125000>;
hysteresis = <2000>;
type = "critical";
};
};
};
};
};
&spmi_bus {
pmic@0 {
compatible = "qcom,pm8994", "qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
rtc@6000 {
compatible = "qcom,pm8941-rtc";
reg = <0x6000>, <0x6100>;
reg-names = "rtc", "alarm";
interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
};
pm8994_pon: pon@800 {
compatible = "qcom,pm8916-pon";
reg = <0x800>;
mode-bootloader = <0x2>;
mode-recovery = <0x1>;
pwrkey {
compatible = "qcom,pm8941-pwrkey";
interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
debounce = <15625>;
bias-pull-up;
linux,code = <KEY_POWER>;
};
pm8994_resin: resin {
compatible = "qcom,pm8941-resin";
interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
debounce = <15625>;
bias-pull-up;
status = "disabled";
};
};
pm8994_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>;
interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>;
io-channels = <&pm8994_vadc VADC_DIE_TEMP>;
io-channel-names = "thermal";
#thermal-sensor-cells = <0>;
};
pm8994_vadc: adc@3100 {
compatible = "qcom,spmi-vadc";
reg = <0x3100>;
interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
#address-cells = <1>;
#size-cells = <0>;
#io-channel-cells = <1>;
channel@7 {
reg = <VADC_VSYS>;
qcom,pre-scaling = <1 3>;
label = "vph_pwr";
};
channel@8 {
reg = <VADC_DIE_TEMP>;
label = "die_temp";
};
channel@9 {
reg = <VADC_REF_625MV>;
label = "ref_625mv";
};
channel@a {
reg = <VADC_REF_1250MV>;
label = "ref_1250mv";
};
channel@e {
reg = <VADC_GND_REF>;
};
channel@f {
reg = <VADC_VDD_VADC>;
};
};
pm8994_gpios: gpio@c000 {
compatible = "qcom,pm8994-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
gpio-controller;
gpio-ranges = <&pm8994_gpios 0 0 22>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
pm8994_mpps: mpps@a000 {
compatible = "qcom,pm8994-mpp", "qcom,spmi-mpp";
reg = <0xa000>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&pm8994_mpps 0 0 8>;
interrupt-controller;
#interrupt-cells = <2>;
};
};
pmic@1 {
compatible = "qcom,pm8994", "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
pm8994_lpg: pwm {
compatible = "qcom,pm8994-lpg";
#address-cells = <1>;
#size-cells = <0>;
#pwm-cells = <2>;
status = "disabled";
};
pm8994_spmi_regulators: regulators {
compatible = "qcom,pm8994-regulators";
};
};
};

View File

@@ -1,130 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/* Copyright 2018 Google LLC. */
#include <dt-bindings/iio/qcom,spmi-vadc.h>
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/spmi/spmi.h>
#include <dt-bindings/thermal/thermal.h>
/ {
thermal-zones {
pm8998-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
thermal-sensors = <&pm8998_temp>;
trips {
pm8998_alert0: pm8998-alert0 {
temperature = <105000>;
hysteresis = <2000>;
type = "passive";
};
pm8998_crit: pm8998-crit {
temperature = <125000>;
hysteresis = <2000>;
type = "critical";
};
};
};
};
};
&spmi_bus {
pm8998_lsid0: pmic@0 {
compatible = "qcom,pm8998", "qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
pm8998_pon: pon@800 {
compatible = "qcom,pm8998-pon";
reg = <0x800>;
mode-bootloader = <0x2>;
mode-recovery = <0x1>;
pm8998_pwrkey: pwrkey {
compatible = "qcom,pm8941-pwrkey";
interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
debounce = <15625>;
bias-pull-up;
linux,code = <KEY_POWER>;
};
pm8998_resin: resin {
compatible = "qcom,pm8941-resin";
interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
debounce = <15625>;
bias-pull-up;
status = "disabled";
};
};
pm8998_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>;
interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>;
io-channels = <&pm8998_adc ADC5_DIE_TEMP>;
io-channel-names = "thermal";
#thermal-sensor-cells = <0>;
};
pm8998_coincell: charger@2800 {
compatible = "qcom,pm8998-coincell", "qcom,pm8941-coincell";
reg = <0x2800>;
status = "disabled";
};
pm8998_adc: adc@3100 {
compatible = "qcom,spmi-adc-rev2";
reg = <0x3100>;
interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
#address-cells = <1>;
#size-cells = <0>;
#io-channel-cells = <1>;
channel@6 {
reg = <ADC5_DIE_TEMP>;
label = "die_temp";
};
};
pm8998_adc_tm: adc-tm@3400 {
compatible = "qcom,spmi-adc-tm-hc";
reg = <0x3400>;
interrupts = <0x0 0x34 0x0 IRQ_TYPE_EDGE_RISING>;
#thermal-sensor-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
rtc@6000 {
compatible = "qcom,pm8941-rtc";
reg = <0x6000>, <0x6100>;
reg-names = "rtc", "alarm";
interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
};
pm8998_gpios: gpio@c000 {
compatible = "qcom,pm8998-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
gpio-controller;
gpio-ranges = <&pm8998_gpios 0 0 26>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
};
pm8998_lsid1: pmic@1 {
compatible = "qcom,pm8998", "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
};
};

View File

@@ -1,65 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/spmi/spmi.h>
&spmi_bus {
pmic@2 {
compatible = "qcom,pmi8994", "qcom,spmi-pmic";
reg = <0x2 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
pmi8994_gpios: gpio@c000 {
compatible = "qcom,pmi8994-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
gpio-controller;
gpio-ranges = <&pmi8994_gpios 0 0 10>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
pmi8994_mpps: mpps@a000 {
compatible = "qcom,pmi8994-mpp", "qcom,spmi-mpp";
reg = <0xa000>;
gpio-controller;
gpio-ranges = <&pmi8994_mpps 0 0 4>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
};
pmic@3 {
compatible = "qcom,pmi8994", "qcom,spmi-pmic";
reg = <0x3 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
pmi8994_lpg: pwm {
compatible = "qcom,pmi8994-lpg";
#address-cells = <1>;
#size-cells = <0>;
#pwm-cells = <2>;
status = "disabled";
};
pmi8994_spmi_regulators: regulators {
compatible = "qcom,pmi8994-regulators";
};
pmi8994_wled: wled@d800 {
compatible = "qcom,pmi8994-wled";
reg = <0xd800>, <0xd900>;
interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>,
<0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "ovp", "short";
qcom,cabc;
qcom,external-pfet;
status = "disabled";
};
};
};

View File

@@ -1,98 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/spmi/spmi.h>
&spmi_bus {
pmi8998_lsid0: pmic@2 {
compatible = "qcom,pmi8998", "qcom,spmi-pmic";
reg = <0x2 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
pmi8998_charger: charger@1000 {
compatible = "qcom,pmi8998-charger";
reg = <0x1000>;
interrupts = <0x2 0x13 0x4 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x12 0x2 IRQ_TYPE_EDGE_BOTH>,
<0x2 0x16 0x1 IRQ_TYPE_EDGE_RISING>,
<0x2 0x13 0x6 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "usb-plugin",
"bat-ov",
"wdog-bark",
"usbin-icl-change";
io-channels = <&pmi8998_rradc 3>,
<&pmi8998_rradc 4>;
io-channel-names = "usbin_i", "usbin_v";
status = "disabled";
};
pmi8998_gpios: gpio@c000 {
compatible = "qcom,pmi8998-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
gpio-controller;
gpio-ranges = <&pmi8998_gpios 0 0 14>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
pmi8998_rradc: adc@4500 {
compatible = "qcom,pmi8998-rradc";
reg = <0x4500>;
#io-channel-cells = <1>;
};
};
pmi8998_lsid1: pmic@3 {
compatible = "qcom,pmi8998", "qcom,spmi-pmic";
reg = <0x3 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
labibb {
compatible = "qcom,pmi8998-lab-ibb";
ibb: ibb {
interrupts = <0x3 0xdc 0x2 IRQ_TYPE_EDGE_RISING>,
<0x3 0xdc 0x0 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "sc-err", "ocp";
};
lab: lab {
interrupts = <0x3 0xde 0x1 IRQ_TYPE_EDGE_RISING>,
<0x3 0xde 0x0 IRQ_TYPE_LEVEL_LOW>;
interrupt-names = "sc-err", "ocp";
};
};
pmi8998_lpg: pwm {
compatible = "qcom,pmi8998-lpg";
#address-cells = <1>;
#size-cells = <0>;
#pwm-cells = <2>;
status = "disabled";
};
pmi8998_flash: led-controller@d300 {
compatible = "qcom,pmi8998-flash-led", "qcom,spmi-flash-led";
reg = <0xd300>;
status = "disabled";
};
pmi8998_wled: leds@d800 {
compatible = "qcom,pmi8998-wled";
reg = <0xd800>, <0xd900>;
interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>,
<0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "ovp", "short";
label = "backlight";
status = "disabled";
};
};
};

View File

@@ -1,149 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018, Linaro Limited
*/
#include <dt-bindings/spmi/spmi.h>
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/iio/qcom,spmi-vadc.h>
#include <dt-bindings/thermal/thermal.h>
/ {
thermal-zones {
pms405-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
thermal-sensors = <&pms405_temp>;
trips {
pms405_alert0: pms405-alert0 {
temperature = <105000>;
hysteresis = <2000>;
type = "passive";
};
pms405_crit: pms405-crit {
temperature = <125000>;
hysteresis = <2000>;
type = "critical";
};
};
};
};
};
&spmi_bus {
pms405_0: pms405@0 {
compatible = "qcom,pms405", "qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
#address-cells = <1>;
#size-cells = <0>;
pms405_gpios: gpio@c000 {
compatible = "qcom,pms405-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
gpio-controller;
gpio-ranges = <&pms405_gpios 0 0 12>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
pon@800 {
compatible = "qcom,pms405-pon";
reg = <0x0800>;
mode-bootloader = <0x2>;
mode-recovery = <0x1>;
pwrkey {
compatible = "qcom,pm8941-pwrkey";
interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
debounce = <15625>;
bias-pull-up;
linux,code = <KEY_POWER>;
};
};
pms405_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>;
interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>;
io-channels = <&pms405_adc ADC5_DIE_TEMP>;
io-channel-names = "thermal";
#thermal-sensor-cells = <0>;
};
pms405_adc: adc@3100 {
compatible = "qcom,pms405-adc", "qcom,spmi-adc-rev2";
reg = <0x3100>;
interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
#address-cells = <1>;
#size-cells = <0>;
#io-channel-cells = <1>;
channel@0 {
reg = <ADC5_REF_GND>;
qcom,pre-scaling = <1 1>;
label = "ref_gnd";
};
channel@1 {
reg = <ADC5_1P25VREF>;
qcom,pre-scaling = <1 1>;
label = "vref_1p25";
};
channel@131 {
reg = <ADC5_VPH_PWR>;
qcom,pre-scaling = <1 3>;
label = "vph_pwr";
};
channel@6 {
reg = <ADC5_DIE_TEMP>;
qcom,pre-scaling = <1 1>;
label = "die_temp";
};
channel@77 {
reg = <ADC5_AMUX_THM1_100K_PU>;
qcom,ratiometric;
qcom,hw-settle-time = <200>;
qcom,pre-scaling = <1 1>;
label = "pa_therm1";
};
channel@79 {
reg = <ADC5_AMUX_THM3_100K_PU>;
qcom,ratiometric;
qcom,hw-settle-time = <200>;
qcom,pre-scaling = <1 1>;
label = "pa_therm3";
};
channel@76 {
reg = <ADC5_XO_THERM_100K_PU>;
qcom,ratiometric;
qcom,hw-settle-time = <200>;
qcom,pre-scaling = <1 1>;
label = "xo_therm";
};
};
rtc@6000 {
compatible = "qcom,pm8941-rtc";
reg = <0x6000>, <0x6100>;
reg-names = "rtc", "alarm";
interrupts = <0x0 0x61 0x1 IRQ_TYPE_NONE>;
};
};
pms405_1: pms405@1 {
compatible = "qcom,pms405", "qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
pms405_spmi_regulators: regulators {
compatible = "qcom,pms405-regulators";
};
};
};

View File

@@ -1,96 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018, Linaro Limited
*/
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include "qcs404-evb.dtsi"
/ {
model = "Qualcomm Technologies, Inc. QCS404 EVB 4000";
compatible = "qcom,qcs404-evb-4000", "qcom,qcs404-evb",
"qcom,qcs404";
};
&ethernet {
status = "okay";
snps,reset-gpio = <&tlmm 60 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 10000>;
pinctrl-names = "default";
pinctrl-0 = <&ethernet_defaults>;
phy-handle = <&phy1>;
phy-mode = "rgmii";
mdio {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dwmac-mdio";
phy1: phy@4 {
compatible = "ethernet-phy-ieee802.3-c22";
device_type = "ethernet-phy";
reg = <0x4>;
};
};
};
&tlmm {
ethernet_defaults: ethernet-defaults-state {
int-pins {
pins = "gpio61";
function = "rgmii_int";
bias-disable;
drive-strength = <2>;
};
mdc-pins {
pins = "gpio76";
function = "rgmii_mdc";
bias-pull-up;
};
mdio-pins {
pins = "gpio75";
function = "rgmii_mdio";
bias-pull-up;
};
tx-pins {
pins = "gpio67", "gpio66", "gpio65", "gpio64";
function = "rgmii_tx";
bias-pull-up;
drive-strength = <16>;
};
rx-pins {
pins = "gpio73", "gpio72", "gpio71", "gpio70";
function = "rgmii_rx";
bias-disable;
drive-strength = <2>;
};
tx-ctl-pins {
pins = "gpio68";
function = "rgmii_ctl";
bias-pull-up;
drive-strength = <16>;
};
rx-ctl-pins {
pins = "gpio74";
function = "rgmii_ctl";
bias-disable;
drive-strength = <2>;
};
tx-ck-pins {
pins = "gpio63";
function = "rgmii_ck";
bias-pull-up;
drive-strength = <16>;
};
rx-ck-pins {
pins = "gpio69";
function = "rgmii_ck";
bias-disable;
drive-strength = <2>;
};
};
};

View File

@@ -1,389 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018, Linaro Limited
*/
#include <dt-bindings/gpio/gpio.h>
#include "qcs404.dtsi"
#include "pms405.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
/ {
aliases {
serial0 = &blsp1_uart2;
serial1 = &blsp1_uart3;
};
chosen {
stdout-path = "serial0";
};
vph_pwr: vph-pwr-regulator {
compatible = "regulator-fixed";
regulator-name = "vph_pwr";
regulator-always-on;
regulator-boot-on;
};
vdd_ch0_3p3:
vdd_esmps3_3p3: vdd-esmps3-3p3-regulator {
compatible = "regulator-fixed";
regulator-name = "eSMPS3_3P3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
usb3_vbus_reg: regulator-usb3-vbus {
compatible = "regulator-fixed";
regulator-name = "VBUS_BOOST_5V";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&pms405_gpios 3 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&usb_vbus_boost_pin>;
vin-supply = <&vph_pwr>;
enable-active-high;
/* TODO: Drop this when introducing role switching */
regulator-always-on;
};
};
&blsp1_uart3 {
status = "okay";
bluetooth {
compatible = "qcom,wcn3990-bt";
vddio-supply = <&vreg_l6_1p8>;
vddxo-supply = <&vreg_l5_1p8>;
vddrf-supply = <&vreg_l1_1p3>;
vddch0-supply = <&vdd_ch0_3p3>;
local-bd-address = [ 02 00 00 00 5a ad ];
max-speed = <3200000>;
};
};
&blsp1_dma {
qcom,controlled-remotely;
};
&blsp2_dma {
qcom,controlled-remotely;
};
&gcc {
protected-clocks = <GCC_BIMC_CDSP_CLK>,
<GCC_CDSP_CFG_AHB_CLK>,
<GCC_CDSP_BIMC_CLK_SRC>,
<GCC_CDSP_TBU_CLK>,
<141>, /* GCC_WCSS_Q6_AHB_CLK */
<142>; /* GCC_WCSS_Q6_AXIM_CLK */
};
&pms405_spmi_regulators {
vdd_s3-supply = <&vph_pwr>;
pms405_s3: s3 {
regulator-always-on;
regulator-boot-on;
regulator-name = "vdd_apc";
regulator-initial-mode = <1>;
regulator-min-microvolt = <1048000>;
regulator-max-microvolt = <1384000>;
};
};
&pcie {
status = "okay";
perst-gpios = <&tlmm 43 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&perst_state>;
};
&pcie_phy {
status = "okay";
vdda-vp-supply = <&vreg_l3_1p05>;
vdda-vph-supply = <&vreg_l5_1p8>;
};
&remoteproc_adsp {
status = "okay";
};
&remoteproc_cdsp {
status = "okay";
};
&remoteproc_wcss {
status = "okay";
};
&rpm_requests {
regulators {
compatible = "qcom,rpm-pms405-regulators";
vdd_s1-supply = <&vph_pwr>;
vdd_s2-supply = <&vph_pwr>;
vdd_s3-supply = <&vph_pwr>;
vdd_s4-supply = <&vph_pwr>;
vdd_s5-supply = <&vph_pwr>;
vdd_l1_l2-supply = <&vreg_s5_1p35>;
vdd_l3_l8-supply = <&vreg_s5_1p35>;
vdd_l4-supply = <&vreg_s5_1p35>;
vdd_l5_l6-supply = <&vreg_s4_1p8>;
vdd_l7-supply = <&vph_pwr>;
vdd_l9-supply = <&vreg_s5_1p35>;
vdd_l10_l11_l12_l13-supply = <&vph_pwr>;
vreg_s4_1p8: s4 {
regulator-min-microvolt = <1728000>;
regulator-max-microvolt = <1920000>;
};
vreg_s5_1p35: s5 {
regulator-min-microvolt = <1352000>;
regulator-max-microvolt = <1352000>;
};
vreg_l1_1p3: l1 {
regulator-min-microvolt = <1240000>;
regulator-max-microvolt = <1352000>;
};
vreg_l2_1p275: l2 {
regulator-min-microvolt = <1048000>;
regulator-max-microvolt = <1280000>;
};
vreg_l3_1p05: l3 {
regulator-min-microvolt = <1048000>;
regulator-max-microvolt = <1160000>;
};
vreg_l4_1p2: l4 {
regulator-min-microvolt = <1144000>;
regulator-max-microvolt = <1256000>;
};
vreg_l5_1p8: l5 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
vreg_l6_1p8: l6 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
vreg_l7_1p8: l7 {
regulator-min-microvolt = <1616000>;
regulator-max-microvolt = <3000000>;
};
vreg_l8_1p2: l8 {
regulator-min-microvolt = <1136000>;
regulator-max-microvolt = <1352000>;
};
vreg_l10_3p3: l10 {
regulator-min-microvolt = <2936000>;
regulator-max-microvolt = <3088000>;
};
vreg_l11_sdc2: l11 {
regulator-min-microvolt = <2696000>;
regulator-max-microvolt = <3304000>;
};
vreg_l12_3p3: l12 {
regulator-min-microvolt = <3050000>;
regulator-max-microvolt = <3300000>;
};
vreg_l13_3p3: l13 {
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3300000>;
};
};
};
&sdcc1 {
status = "okay";
supports-cqe;
mmc-ddr-1_8v;
mmc-hs400-1_8v;
bus-width = <8>;
non-removable;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&sdc1_on>;
pinctrl-1 = <&sdc1_off>;
};
&tlmm {
perst_state: perst-state {
pins = "gpio43";
function = "gpio";
drive-strength = <2>;
bias-disable;
output-low;
};
sdc1_on: sdc1-on-state {
clk-pins {
pins = "sdc1_clk";
bias-disable;
drive-strength = <16>;
};
cmd-pins {
pins = "sdc1_cmd";
bias-pull-up;
drive-strength = <10>;
};
data-pins {
pins = "sdc1_data";
bias-pull-up;
drive-strength = <10>;
};
rclk-pins {
pins = "sdc1_rclk";
bias-pull-down;
};
};
sdc1_off: sdc1-off-state {
clk-pins {
pins = "sdc1_clk";
bias-disable;
drive-strength = <2>;
};
cmd-pins {
pins = "sdc1_cmd";
bias-pull-up;
drive-strength = <2>;
};
data-pins {
pins = "sdc1_data";
bias-pull-up;
drive-strength = <2>;
};
rclk-pins {
pins = "sdc1_rclk";
bias-pull-down;
};
};
usb3_id_pin: usb3-id-state {
pins = "gpio116";
function = "gpio";
drive-strength = <2>;
bias-pull-up;
};
};
&pms405_gpios {
usb_vbus_boost_pin: usb-vbus-boost-state {
pinconf {
pins = "gpio3";
function = PMIC_GPIO_FUNC_NORMAL;
output-low;
power-source = <1>;
};
};
usb3_vbus_pin: usb3-vbus-state {
pinconf {
pins = "gpio12";
function = PMIC_GPIO_FUNC_NORMAL;
input-enable;
bias-pull-down;
power-source = <1>;
};
};
};
&usb2 {
status = "okay";
};
&usb2_phy_sec {
vdd-supply = <&vreg_l4_1p2>;
vdda1p8-supply = <&vreg_l5_1p8>;
vdda3p3-supply = <&vreg_l12_3p3>;
status = "okay";
};
&usb3 {
status = "okay";
};
&usb3_dwc3 {
dr_mode = "host";
};
&usb2_phy_prim {
vdd-supply = <&vreg_l4_1p2>;
vdda1p8-supply = <&vreg_l5_1p8>;
vdda3p3-supply = <&vreg_l12_3p3>;
status = "okay";
};
&usb3_phy {
vdd-supply = <&vreg_l3_1p05>;
vdda1p8-supply = <&vreg_l5_1p8>;
status = "okay";
};
&wifi {
status = "okay";
vdd-0.8-cx-mx-supply = <&vreg_l2_1p275>;
vdd-1.8-xo-supply = <&vreg_l5_1p8>;
vdd-1.3-rfa-supply = <&vreg_l1_1p3>;
};
/* PINCTRL - additions to nodes defined in qcs404.dtsi */
&blsp1_uart2_default {
rx-pins {
drive-strength = <2>;
bias-disable;
};
tx-pins {
drive-strength = <2>;
bias-disable;
};
};
&blsp1_uart3_default {
cts-pins {
bias-disable;
};
rts-tx-pins {
drive-strength = <2>;
bias-disable;
};
rx-pins {
bias-pull-up;
};
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/* This is usually OTG but U-Boot doesn't support that properly */
&usb_dwc3 {
dr_mode = "host";
};

View File

@@ -7,3 +7,10 @@
&pcie0_3p3v_dual {
regulator-always-on;
};
&sdhc_2 {
/* Remove the unsupported rpmhcc xo clock reference */
clocks = <&gcc GCC_SDCC2_AHB_CLK>,
<&gcc GCC_SDCC2_APPS_CLK>;
clock-names = "iface", "core";
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,460 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* SDM845 Samsung S9 (SM-G9600) (starqltechn / star2qltechn) common device tree source
*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include "sdm845.dtsi"
/ {
chassis-type = "handset";
model = "Samsung Galaxy S9 SM-G9600";
compatible = "samsung,starqltechn", "qcom,sdm845";
chosen {
#address-cells = <2>;
#size-cells = <2>;
ranges;
framebuffer: framebuffer@9d400000 {
compatible = "simple-framebuffer";
reg = <0 0x9d400000 0 (2960 * 1440 * 4)>;//2400000
width = <1440>;
height = <2960>;
stride = <(1440 * 4)>;
format = "a8r8g8b8";
};
};
vph_pwr: vph-pwr-regulator {
compatible = "regulator-fixed";
regulator-name = "vph_pwr";
regulator-min-microvolt = <3700000>;
regulator-max-microvolt = <3700000>;
};
/*
* Apparently RPMh does not provide support for PM8998 S4 because it
* is always-on; model it as a fixed regulator.
*/
vreg_s4a_1p8: pm8998-smps4 {
compatible = "regulator-fixed";
regulator-name = "vreg_s4a_1p8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
vin-supply = <&vph_pwr>;
};
reserved-memory {
memory@9d400000 {
reg = <0x0 0x9d400000 0x0 0x02400000>;
no-map;
};
memory@a1300000 {
compatible = "ramoops";
reg = <0x0 0xa1300000 0x0 0x100000>;
record-size = <0x40000>;
console-size = <0x40000>;
ftrace-size = <0x40000>;
pmsg-size = <0x40000>;
};
};
};
&apps_rsc {
regulators-0 {
compatible = "qcom,pm8998-rpmh-regulators";
qcom,pmic-id = "a";
vdd-s1-supply = <&vph_pwr>;
vdd-s2-supply = <&vph_pwr>;
vdd-s3-supply = <&vph_pwr>;
vdd-s4-supply = <&vph_pwr>;
vdd-s5-supply = <&vph_pwr>;
vdd-s6-supply = <&vph_pwr>;
vdd-s7-supply = <&vph_pwr>;
vdd-s8-supply = <&vph_pwr>;
vdd-s9-supply = <&vph_pwr>;
vdd-s10-supply = <&vph_pwr>;
vdd-s11-supply = <&vph_pwr>;
vdd-s12-supply = <&vph_pwr>;
vdd-s13-supply = <&vph_pwr>;
vdd-l1-l27-supply = <&vreg_s7a_1p025>;
vdd-l2-l8-l17-supply = <&vreg_s3a_1p35>;
vdd-l3-l11-supply = <&vreg_s7a_1p025>;
vdd-l4-l5-supply = <&vreg_s7a_1p025>;
vdd-l6-supply = <&vph_pwr>;
vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p04>;
vdd-l26-supply = <&vreg_s3a_1p35>;
vin-lvs-1-2-supply = <&vreg_s4a_1p8>;
vreg_s2a_1p125: smps2 {
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
};
vreg_s3a_1p35: smps3 {
regulator-min-microvolt = <1352000>;
regulator-max-microvolt = <1352000>;
};
vreg_s5a_2p04: smps5 {
regulator-min-microvolt = <1904000>;
regulator-max-microvolt = <2040000>;
};
vreg_s7a_1p025: smps7 {
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1028000>;
};
vdd_qusb_hs0:
vdda_hp_pcie_core:
vdda_mipi_csi0_0p9:
vdda_mipi_csi1_0p9:
vdda_mipi_csi2_0p9:
vdda_mipi_dsi0_pll:
vdda_mipi_dsi1_pll:
vdda_qlink_lv:
vdda_qlink_lv_ck:
vdda_qrefs_0p875:
vdda_pcie_core:
vdda_pll_cc_ebi01:
vdda_pll_cc_ebi23:
vdda_sp_sensor:
vdda_ufs1_core:
vdda_ufs2_core:
vdda_usb1_ss_core:
vdda_usb2_ss_core:
vreg_l1a_0p875: ldo1 {
regulator-min-microvolt = <880000>;
regulator-max-microvolt = <880000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vddpx_10:
vreg_l2a_1p2: ldo2 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
regulator-always-on;
};
vreg_l3a_1p0: ldo3 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vdd_wcss_cx:
vdd_wcss_mx:
vdda_wcss_pll:
vreg_l5a_0p8: ldo5 {
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vddpx_13:
vreg_l6a_1p8: ldo6 {
regulator-min-microvolt = <1856000>;
regulator-max-microvolt = <1856000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l7a_1p8: ldo7 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l8a_1p2: ldo8 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1248000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l9a_1p8: ldo9 {
regulator-min-microvolt = <1704000>;
regulator-max-microvolt = <2928000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l10a_1p8: ldo10 {
regulator-min-microvolt = <1704000>;
regulator-max-microvolt = <2928000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l11a_1p0: ldo11 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1048000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vdd_qfprom:
vdd_qfprom_sp:
vdda_apc1_cs_1p8:
vdda_gfx_cs_1p8:
vdda_qrefs_1p8:
vdda_qusb_hs0_1p8:
vddpx_11:
vreg_l12a_1p8: ldo12 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vddpx_2:
vreg_l13a_2p95: ldo13 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2960000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l14a_1p88: ldo14 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l15a_1p8: ldo15 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l16a_2p7: ldo16 {
regulator-min-microvolt = <2704000>;
regulator-max-microvolt = <2704000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l17a_1p3: ldo17 {
regulator-min-microvolt = <1304000>;
regulator-max-microvolt = <1304000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l18a_2p7: ldo18 {
regulator-min-microvolt = <2704000>;
regulator-max-microvolt = <2960000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l19a_3p0: ldo19 {
regulator-min-microvolt = <2856000>;
regulator-max-microvolt = <3104000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l20a_2p95: ldo20 {
regulator-min-microvolt = <2704000>;
regulator-max-microvolt = <2960000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l21a_2p95: ldo21 {
regulator-min-microvolt = <2704000>;
regulator-max-microvolt = <2960000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l22a_2p85: ldo22 {
regulator-min-microvolt = <2864000>;
regulator-max-microvolt = <3312000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l23a_3p3: ldo23 {
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3312000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vdda_qusb_hs0_3p1:
vreg_l24a_3p075: ldo24 {
regulator-min-microvolt = <3088000>;
regulator-max-microvolt = <3088000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l25a_3p3: ldo25 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3312000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vdda_hp_pcie_1p2:
vdda_hv_ebi0:
vdda_hv_ebi1:
vdda_hv_ebi2:
vdda_hv_ebi3:
vdda_mipi_csi_1p25:
vdda_mipi_dsi0_1p2:
vdda_mipi_dsi1_1p2:
vdda_pcie_1p2:
vdda_ufs1_1p2:
vdda_ufs2_1p2:
vdda_usb1_ss_1p2:
vdda_usb2_ss_1p2:
vreg_l26a_1p2: ldo26 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_l28a_3p0: ldo28 {
regulator-min-microvolt = <2856000>;
regulator-max-microvolt = <3008000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
};
vreg_lvs1a_1p8: lvs1 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
vreg_lvs2a_1p8: lvs2 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
};
regulators-1 {
compatible = "qcom,pm8005-rpmh-regulators";
qcom,pmic-id = "c";
vdd-s1-supply = <&vph_pwr>;
vdd-s2-supply = <&vph_pwr>;
vdd-s3-supply = <&vph_pwr>;
vdd-s4-supply = <&vph_pwr>;
vreg_s3c_0p6: smps3 {
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <600000>;
};
};
};
&gcc {
protected-clocks = <GCC_QSPI_CORE_CLK>,
<GCC_QSPI_CORE_CLK_SRC>,
<GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
<GCC_LPASS_Q6_AXI_CLK>,
<GCC_LPASS_SWAY_CLK>;
};
&i2c10 {
clock-frequency = <400000>;
status = "okay";
};
&qupv3_id_1 {
status = "okay";
};
&uart9 {
status = "okay";
};
&ufs_mem_hc {
reset-gpios = <&tlmm 150 GPIO_ACTIVE_LOW>;
vcc-supply = <&vreg_l20a_2p95>;
vcc-max-microamp = <600000>;
status = "okay";
};
&ufs_mem_phy {
vdda-phy-supply = <&vdda_ufs1_core>;
vdda-pll-supply = <&vdda_ufs1_1p2>;
status = "okay";
};
&sdhc_2 {
pinctrl-names = "default";
pinctrl-0 = <&sdc2_clk_state &sdc2_cmd_state &sdc2_data_state &sd_card_det_n_state>;
cd-gpios = <&tlmm 126 GPIO_ACTIVE_LOW>;
vmmc-supply = <&vreg_l21a_2p95>;
vqmmc-supply = <&vddpx_2>;
status = "okay";
};
&usb_1 {
status = "okay";
};
&usb_1_dwc3 {
/* Until we have Type C hooked up we'll force this as peripheral. */
dr_mode = "peripheral";
};
&usb_1_hsphy {
vdd-supply = <&vdda_usb1_ss_core>;
vdda-pll-supply = <&vdda_qusb_hs0_1p8>;
vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>;
qcom,imp-res-offset-value = <8>;
qcom,hstx-trim-value = <QUSB2_V2_HSTX_TRIM_21_6_MA>;
qcom,preemphasis-level = <QUSB2_V2_PREEMPHASIS_5_PERCENT>;
qcom,preemphasis-width = <QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT>;
status = "okay";
};
&usb_1_qmpphy {
vdda-phy-supply = <&vdda_usb1_ss_1p2>;
vdda-pll-supply = <&vdda_usb1_ss_core>;
status = "okay";
};
&wifi {
vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
status = "okay";
};
&tlmm {
gpio-reserved-ranges = <0 4>, <27 4>, <81 4>, <85 4>;
sdc2_clk_state: sdc2-clk-state {
pins = "sdc2_clk";
bias-disable;
/*
* It seems that mmc_test reports errors if drive
* strength is not 16 on clk, cmd, and data pins.
*/
drive-strength = <16>;
};
sdc2_cmd_state: sdc2-cmd-state {
pins = "sdc2_cmd";
bias-pull-up;
drive-strength = <16>;
};
sdc2_data_state: sdc2-data-state {
pins = "sdc2_data";
bias-pull-up;
drive-strength = <16>;
};
sd_card_det_n_state: sd-card-det-n-state {
pins = "gpio126";
function = "gpio";
bias-pull-up;
};
};

View File

@@ -1,86 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* SDM845 SoC device tree source
*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
&slim {
status = "okay";
slim@1 {
reg = <1>;
#address-cells = <2>;
#size-cells = <0>;
wcd9340_ifd: ifd@0,0 {
compatible = "slim217,250";
reg = <0 0>;
};
wcd9340: codec@1,0 {
compatible = "slim217,250";
reg = <1 0>;
slim-ifc-dev = <&wcd9340_ifd>;
#sound-dai-cells = <1>;
interrupts-extended = <&tlmm 54 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <1>;
clock-names = "extclk";
clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
#clock-cells = <0>;
clock-frequency = <9600000>;
clock-output-names = "mclk";
pinctrl-0 = <&wcd_intr_default>;
pinctrl-names = "default";
qcom,micbias1-microvolt = <1800000>;
qcom,micbias2-microvolt = <1800000>;
qcom,micbias3-microvolt = <1800000>;
qcom,micbias4-microvolt = <1800000>;
#address-cells = <1>;
#size-cells = <1>;
wcdgpio: gpio-controller@42 {
compatible = "qcom,wcd9340-gpio";
gpio-controller;
#gpio-cells = <2>;
reg = <0x42 0x2>;
};
swm: swm@c85 {
compatible = "qcom,soundwire-v1.3.0";
reg = <0xc85 0x40>;
interrupts-extended = <&wcd9340 20>;
qcom,dout-ports = <6>;
qcom,din-ports = <2>;
qcom,ports-sinterval-low = /bits/ 8 <0x07 0x1f 0x3f 0x7 0x1f 0x3f 0x0f 0x0f>;
qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0c 0x6 0x12 0x0d 0x07 0x0a>;
qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x1f 0x00 0x00 0x1f 0x00 0x00>;
#sound-dai-cells = <1>;
clocks = <&wcd9340>;
clock-names = "iface";
#address-cells = <2>;
#size-cells = <0>;
};
};
};
};
&tlmm {
wcd_intr_default: wcd-intr-default-state {
pins = "gpio54";
function = "gpio";
bias-pull-down;
drive-strength = <2>;
};
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Empty gpio.h
* Qualcomm common pin control data.
*
* This file must stay as arch/arm/include/asm/gpio.h requires it.
*
* Copyright (c) 2019 Sartura Ltd.
*
* Author: Robert Marko <robert.marko@sartura.hr>
* Copyright (C) 2023 Linaro Ltd.
*/
#ifndef _QCOM_GPIO_H_
#define _QCOM_GPIO_H_
#include <asm/types.h>
#include <stdbool.h>
struct msm_pin_data {
int pin_count;
const unsigned int *pin_offsets;
/* Index of first special pin, these are ignored for now */
unsigned int special_pins_start;
};
static inline u32 qcom_pin_offset(const unsigned int *offs, unsigned int selector)
{
u32 out = (selector * 0x1000);
if (offs)
return out + offs[selector];
return out;
}
static inline bool qcom_is_special_pin(const struct msm_pin_data *pindata, unsigned int pin)
{
return pindata->special_pins_start && pin >= pindata->special_pins_start;
}
#endif /* _QCOM_GPIO_H_ */

View File

@@ -4,7 +4,12 @@ config SYS_SOC
default "snapdragon"
config SYS_VENDOR
string "Snapdragon board vendor"
default "qualcomm"
help
Allows to specify vendor for the Snapdragon SoCs based boards.
Based on this option board/<CONFIG_SYS_VENDOR>/<CONFIG_SYS_BOARD>
will be used as the custom board directory.
config SYS_MALLOC_F_LEN
default 0x2000
@@ -19,12 +24,11 @@ config LNX_KRNL_IMG_TEXT_OFFSET_BASE
default 0x80000000
config SYS_BOARD
string "Qualcomm custom board"
string "Snapdragon SoCs based board"
help
The Dragonboard 410c and 820c have additional board init
code that isn't shared with other Qualcomm boards.
Based on this option board/qualcomm/<CONFIG_SYS_BOARD> will
be used.
Allows to specify the Snapdragon SoCs based board name.
Based on this option board/<CONFIG_SYS_VENDOR>/<CONFIG_SYS_BOARD>
will be used as the custom board directory.
config SYS_CONFIG_NAME
string "Board configuration name"

View File

@@ -17,6 +17,8 @@
* Author: Caleb Connolly <caleb.connolly@linaro.org>
*/
#define pr_fmt(fmt) "of_fixup: " fmt
#include <dt-bindings/input/linux-event-codes.h>
#include <dm/of_access.h>
#include <dm/of.h>
@@ -153,3 +155,21 @@ void qcom_of_fixup_nodes(void)
time_call(fixup_usb_nodes);
time_call(fixup_power_domains);
}
int ft_board_setup(void *blob, struct bd_info __maybe_unused *bd)
{
struct fdt_header *fdt = blob;
int node;
/* We only want to do this fix-up for the RB1 board, quick return for all others */
if (!fdt_node_check_compatible(fdt, 0, "qcom,qrb4210-rb2"))
return 0;
fdt_for_each_node_by_compatible(node, blob, 0, "snps,dwc3") {
log_debug("%s: Setting 'dr_mode' to OTG\n", fdt_get_name(blob, node, NULL));
fdt_setprop_string(fdt, node, "dr_mode", "otg");
break;
}
return 0;
}

View File

@@ -0,0 +1,6 @@
HMIBSC BOARD
M: Sumit Garg <sumit.garg@linaro.org>
S: Maintained
F: board/schneider/hmibsc/
F: include/configs/hmibsc.h
F: configs/hmibsc_defconfig

View File

@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0+ */
loadaddr=0x90000000
bootcmd=
echo "Booting RAUC A/B system";
setenv devtype mmc; setenv devnum 0;
test -n "${BOOT_ORDER}" || setenv BOOT_ORDER "A B";
test -n "${BOOT_A_LEFT}" || setenv BOOT_A_LEFT 3;
test -n "${BOOT_B_LEFT}" || setenv BOOT_B_LEFT 3;
setenv raucslot;
for BOOT_SLOT in "${BOOT_ORDER}"; do
if test "x${raucslot}" != "x"; then
echo "skip remaining slots...";
elif test "x${BOOT_SLOT}" = "xA"; then
if test ${BOOT_A_LEFT} -gt 0; then
setexpr BOOT_A_LEFT ${BOOT_A_LEFT} - 1;
echo "Found valid RAUC slot A";
setenv raucslot "rauc.slot=A";
setenv raucpart A; setenv distro_bootpart 6;
fi;
elif test "x${BOOT_SLOT}" = "xB"; then
if test ${BOOT_B_LEFT} -gt 0; then
setexpr BOOT_B_LEFT ${BOOT_B_LEFT} - 1;
echo "Found valid RAUC slot B";
setenv raucslot "rauc.slot=B";
setenv raucpart B; setenv distro_bootpart 7;
fi;
fi;
done;
if test -n "${raucslot}"; then
setenv bootargs console=ttyMSM1 root=PARTLABEL=rootfs_${raucpart} rw rootwait ${raucslot};
saveenv;
else
echo "No valid RAUC slot found. Resetting tries to 3";
setenv BOOT_A_LEFT 3;
setenv BOOT_B_LEFT 3;
saveenv;
reset;
fi;
load ${devtype} ${devnum}:${distro_bootpart} ${loadaddr} /boot/fitImage && bootm;

View File

@@ -9,7 +9,7 @@ CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x8007fff0
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0x0
CONFIG_DEFAULT_DEVICE_TREE="apq8016-sbc"
CONFIG_DEFAULT_DEVICE_TREE="qcom/apq8016-sbc"
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_IDENT_STRING="\nQualcomm-DragonBoard 410C"
CONFIG_SYS_LOAD_ADDR=0x80080000

View File

@@ -7,7 +7,7 @@ CONFIG_SYS_MALLOC_LEN=0x804000
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x8007fff0
CONFIG_ENV_SIZE=0x4000
CONFIG_DEFAULT_DEVICE_TREE="apq8096-db820c"
CONFIG_DEFAULT_DEVICE_TREE="qcom/apq8096-db820c"
CONFIG_IDENT_STRING="\nQualcomm-DragonBoard 820C"
CONFIG_SYS_LOAD_ADDR=0x80080000
CONFIG_DISTRO_DEFAULTS=y

87
configs/hmibsc_defconfig Normal file
View File

@@ -0,0 +1,87 @@
CONFIG_ARM=y
CONFIG_SYS_VENDOR="schneider"
CONFIG_SYS_BOARD="hmibsc"
CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK=y
CONFIG_ARCH_SNAPDRAGON=y
CONFIG_TEXT_BASE=0x8f600000
CONFIG_SYS_MALLOC_LEN=0x802000
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x8007fff0
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0x0
CONFIG_DEFAULT_DEVICE_TREE="apq8016-schneider-hmibsc"
# CONFIG_OF_UPSTREAM is not set
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_IDENT_STRING="\nSchneider Electric-HMIBSC"
CONFIG_SYS_LOAD_ADDR=0x80080000
CONFIG_REMAKE_ELF=y
# CONFIG_ANDROID_BOOT_IMAGE is not set
CONFIG_FIT=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_CBSIZE=2048
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SYS_PROMPT="hmibsc => "
CONFIG_SYS_MAXARGS=64
CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
CONFIG_CMD_FS_GENERIC=y
# CONFIG_CMD_IMI is not set
CONFIG_CMD_MD5SUM=y
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_FAT=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PART=y
CONFIG_CMD_USB=y
CONFIG_BOOTP_BOOTFILESIZE=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_TIMER=y
CONFIG_CMD_ENV_FLAGS=y
CONFIG_CMD_ENV_EXISTS=y
CONFIG_CMD_NVEDIT_INFO=y
CONFIG_ENV_WRITEABLE_LIST=y
CONFIG_ENV_ACCESS_IGNORE_FORCE=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SYS_MMC_ENV_PART=2
CONFIG_BUTTON_QCOM_PMIC=y
CONFIG_CLK=y
CONFIG_CLK_QCOM_APQ8016=y
CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x91000000
CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_MSM_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_MSM=y
CONFIG_PHY=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_PINCTRL_QCOM_APQ8016=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_QCOM=y
CONFIG_MSM_SERIAL=y
CONFIG_SPMI_MSM=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MSM=y
CONFIG_USB_ULPI_VIEWPORT=y
CONFIG_USB_ULPI=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_USB_ETHER_ASIX88179=y
CONFIG_USB_ETHER_MCS7830=y
CONFIG_USB_ETHER_SMSC95XX=y
CONFIG_PHYLIB=y
CONFIG_USB_ETHER_LAN75XX=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VENDOR_NUM=0x18d1
CONFIG_USB_GADGET_PRODUCT_NUM=0xd00d
CONFIG_CI_UDC=y

View File

@@ -2,8 +2,9 @@ CONFIG_ARM=y
CONFIG_SKIP_LOWLEVEL_INIT=y
CONFIG_POSITION_INDEPENDENT=y
CONFIG_ARCH_SNAPDRAGON=y
CONFIG_DEFAULT_DEVICE_TREE="sdm845-db845c"
CONFIG_SYS_LOAD_ADDR=0x0
CONFIG_DEFAULT_DEVICE_TREE="qcom/sdm845-db845c"
CONFIG_SYS_LOAD_ADDR=0xA0000000
CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864
CONFIG_BUTTON_CMD=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
@@ -33,14 +34,21 @@ CONFIG_CMD_CAT=y
CONFIG_CMD_BMP=y
CONFIG_CMD_LOG=y
CONFIG_OF_LIVE=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_BUTTON_QCOM_PMIC=y
CONFIG_CLK=y
CONFIG_CLK_QCOM_QCM2290=y
CONFIG_CLK_QCOM_QCS404=y
CONFIG_CLK_QCOM_SDM845=y
CONFIG_CLK_QCOM_SM6115=y
CONFIG_CLK_QCOM_SM8250=y
CONFIG_CLK_QCOM_SM8550=y
CONFIG_CLK_QCOM_SM8650=y
CONFIG_MSM_GPIO=y
CONFIG_QCOM_PMIC_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_QUP=y
CONFIG_SYS_I2C_GENI=y
CONFIG_I2C_MUX=y
CONFIG_DM_KEYBOARD=y
CONFIG_BUTTON_KEYBOARD=y
@@ -63,9 +71,15 @@ CONFIG_RGMII=y
CONFIG_PHY=y
CONFIG_PHY_QCOM_QUSB2=y
CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y
CONFIG_PHY_QCOM_SNPS_EUSB2=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_QCOM_QCM2290=y
CONFIG_PINCTRL_QCOM_QCS404=y
CONFIG_PINCTRL_QCOM_SDM845=y
CONFIG_PINCTRL_QCOM_SM6115=y
CONFIG_PINCTRL_QCOM_SM8250=y
CONFIG_PINCTRL_QCOM_SM8550=y
CONFIG_PINCTRL_QCOM_SM8650=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_QCOM=y
CONFIG_DM_REGULATOR=y
@@ -92,5 +106,5 @@ CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_NO_FB_CLEAR=y
CONFIG_VIDEO_SIMPLE=y
CONFIG_HEXDUMP=y
# CONFIG_GENERATE_SMBIOS_TABLE is not set
CONFIG_GENERATE_SMBIOS_TABLE=y
CONFIG_LMB_MAX_REGIONS=64

View File

@@ -42,6 +42,7 @@ Board-specific doc
renesas/index
rockchip/index
samsung/index
schneider/index
sielaff/index
siemens/index
sifive/index

View File

@@ -0,0 +1,45 @@
.. SPDX-License-Identifier: GPL-2.0+
.. sectionauthor:: Sumit Garg <sumit.garg@linaro.org>
HMIBSC
======
The HMIBSC is an IIoT Edge Box Core board based on the Qualcomm APQ8016E SoC.
More information can be found on the `SE product page`_.
U-Boot can be used as a replacement for Qualcomm's original Android bootloader
(a fork of Little Kernel/LK). Like LK, it is installed directly into the ``aboot``
partition. Note that the U-Boot port used to be loaded as an Android boot image
through LK. This is no longer the case, now U-Boot can replace LK entirely.
.. _SE product page: https://www.se.com/us/en/product/HMIBSCEA53D1L0T/iiot-edge-box-core-harmony-ipc-emmc-dc-linux-tpm/
Build steps
-----------
First, setup ``CROSS_COMPILE`` for aarch64. Then, build U-Boot for ``hmibsc``::
$ export CROSS_COMPILE=<aarch64 toolchain prefix>
$ make hmibsc_defconfig
$ make
This will build ``u-boot.elf`` in the configured output directory.
Installation
------------
Although the HMIBSC does not have secure boot set up by default, the firmware
still expects firmware ELF images to be "signed". The signature does not provide
any security in this case, but it provides the firmware with some required
metadata.
To "sign" ``u-boot.elf`` you can use e.g. `qtestsign`_::
$ ./qtestsign.py aboot u-boot.elf
Then install the resulting ``u-boot-test-signed.mbn`` to the ``aboot`` partition
on your device, e.g. with ``fastboot flash aboot u-boot-test-signed.mbn``.
U-Boot should be running after a reboot (``fastboot reboot``).
.. _qtestsign: https://github.com/msm8916-mainline/qtestsign

View File

@@ -0,0 +1,9 @@
.. SPDX-License-Identifier: GPL-2.0+
Schneider Electric
==================
.. toctree::
:maxdepth: 2
hmibsc

View File

@@ -1,10 +0,0 @@
Qualcomm UART (Data Mover mode)
Required properties:
- compatible: must be "qcom,msm-uartdm-v1.4"
- reg: start address and size of the registers
- clock: interface clock (must accept baudrate as a frequency)
Optional properties:
- bit-rate: Data Mover bit rate register value
(If not defined then 0xCC is used as default)

View File

@@ -19,6 +19,13 @@
#define REG_TYPE 0x4
#define REG_SUBTYPE 0x5
struct qcom_pmic_btn_data {
char *compatible;
unsigned int status_bit;
int code;
char *label;
};
struct qcom_pmic_btn_priv {
u32 base;
u32 status_bit;
@@ -27,11 +34,10 @@ struct qcom_pmic_btn_priv {
};
#define PON_INT_RT_STS 0x10
#define KPDPWR_ON_INT_BIT 0
#define RESIN_ON_INT_BIT 1
#define NODE_IS_PWRKEY(node) (!strncmp(ofnode_get_name(node), "pwrkey", strlen("pwrkey")))
#define NODE_IS_RESIN(node) (!strncmp(ofnode_get_name(node), "resin", strlen("resin")))
#define PON_KPDPWR_N_SET 0
#define PON_RESIN_N_SET 1
#define PON_GEN3_RESIN_N_SET 6
#define PON_GEN3_KPDPWR_N_SET 7
static enum button_state_t qcom_pwrkey_get_state(struct udevice *dev)
{
@@ -52,10 +58,51 @@ static int qcom_pwrkey_get_code(struct udevice *dev)
return priv->code;
}
static const struct qcom_pmic_btn_data qcom_pmic_btn_data_table[] = {
{
.compatible = "qcom,pm8941-pwrkey",
.status_bit = PON_KPDPWR_N_SET,
.code = KEY_ENTER,
.label = "pwrkey",
},
{
.compatible = "qcom,pm8941-resin",
.status_bit = PON_RESIN_N_SET,
.code = KEY_DOWN,
.label = "vol_down",
},
{
.compatible = "qcom,pmk8350-pwrkey",
.status_bit = PON_GEN3_KPDPWR_N_SET,
.code = KEY_ENTER,
.label = "pwrkey",
},
{
.compatible = "qcom,pmk8350-resin",
.status_bit = PON_GEN3_RESIN_N_SET,
.code = KEY_DOWN,
.label = "vol_down",
},
};
static const struct qcom_pmic_btn_data *button_qcom_pmic_match(ofnode node)
{
int i;
for (i = 0; i < ARRAY_SIZE(qcom_pmic_btn_data_table); ++i) {
if (ofnode_device_is_compatible(node,
qcom_pmic_btn_data_table[i].compatible))
return &qcom_pmic_btn_data_table[i];
}
return NULL;
}
static int qcom_pwrkey_probe(struct udevice *dev)
{
struct button_uc_plat *uc_plat = dev_get_uclass_plat(dev);
struct qcom_pmic_btn_priv *priv = dev_get_priv(dev);
const struct qcom_pmic_btn_data *btn_data;
ofnode node = dev_ofnode(dev);
int ret;
u64 base;
@@ -64,6 +111,14 @@ static int qcom_pwrkey_probe(struct udevice *dev)
if (!uc_plat->label)
return 0;
/* Get the data for the node compatible */
btn_data = button_qcom_pmic_match(node);
if (!btn_data)
return -EINVAL;
priv->status_bit = btn_data->status_bit;
priv->code = btn_data->code;
/* the pwrkey and resin nodes are children of the "pon" node, get the
* PMIC device to use in pmic_reg_* calls.
*/
@@ -87,23 +142,10 @@ static int qcom_pwrkey_probe(struct udevice *dev)
ret = pmic_reg_read(priv->pmic, priv->base + REG_SUBTYPE);
if (ret < 0 || (ret & 0x7) == 0) {
printf("%s: unexpected PMCI function subtype %d\n", dev->name, ret);
printf("%s: unexpected PMIC function subtype %d\n", dev->name, ret);
return -ENXIO;
}
if (NODE_IS_PWRKEY(node)) {
priv->status_bit = 0;
priv->code = KEY_ENTER;
} else if (NODE_IS_RESIN(node)) {
priv->status_bit = 1;
priv->code = KEY_DOWN;
} else {
/* Should not get here! */
printf("Invalid pon node '%s' should be 'pwrkey' or 'resin'\n",
ofnode_get_name(node));
return -EINVAL;
}
return 0;
}
@@ -114,12 +156,20 @@ static int button_qcom_pmic_bind(struct udevice *parent)
int ret;
dev_for_each_subnode(node, parent) {
const struct qcom_pmic_btn_data *btn_data;
struct button_uc_plat *uc_plat;
const char *label;
if (!ofnode_is_enabled(node))
continue;
/* Get the data for the node compatible */
btn_data = button_qcom_pmic_match(node);
if (!btn_data) {
debug("Unknown button node '%s'\n", ofnode_get_name(node));
continue;
}
ret = device_bind_driver_to_node(parent, "qcom_pwrkey",
ofnode_get_name(node),
node, &dev);
@@ -128,15 +178,7 @@ static int button_qcom_pmic_bind(struct udevice *parent)
return ret;
}
uc_plat = dev_get_uclass_plat(dev);
if (NODE_IS_PWRKEY(node)) {
uc_plat->label = "pwrkey";
} else if (NODE_IS_RESIN(node)) {
uc_plat->label = "vol_down";
} else {
debug("Unknown button node '%s' should be 'pwrkey' or 'resin'\n",
ofnode_get_name(node));
device_unbind(dev);
}
uc_plat->label = btn_data->label;
}
return 0;
@@ -151,6 +193,7 @@ static const struct udevice_id qcom_pwrkey_ids[] = {
{ .compatible = "qcom,pm8916-pon" },
{ .compatible = "qcom,pm8941-pon" },
{ .compatible = "qcom,pm8998-pon" },
{ .compatible = "qcom,pmk8350-pon" },
{ }
};

View File

@@ -31,6 +31,14 @@ config CLK_QCOM_IPQ4019
on the Snapdragon IPQ4019 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
config CLK_QCOM_QCM2290
bool "Qualcomm QCM2290 GCC"
select CLK_QCOM
help
Say Y here to enable support for the Global Clock Controller
on the Snapdragon QCM2290 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
config CLK_QCOM_QCS404
bool "Qualcomm QCS404 GCC"
select CLK_QCOM
@@ -47,6 +55,37 @@ config CLK_QCOM_SDM845
on the Snapdragon 845 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
config CLK_QCOM_SM6115
bool "Qualcomm SM6115 GCC"
select CLK_QCOM
help
Say Y here to enable support for the Global Clock Controller
on the Snapdragon SM6115 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
config CLK_QCOM_SM8250
bool "Qualcomm SM8250 GCC"
select CLK_QCOM
help
Say Y here to enable support for the Global Clock Controller
on the Snapdragon SM8250 SoC. This driver supports the clocks
config CLK_QCOM_SM8550
bool "Qualcomm SM8550 GCC"
select CLK_QCOM
help
Say Y here to enable support for the Global Clock Controller
on the Snapdragon SM8550 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
config CLK_QCOM_SM8650
bool "Qualcomm SM8650 GCC"
select CLK_QCOM
help
Say Y here to enable support for the Global Clock Controller
on the Snapdragon SM8650 SoC. This driver supports the clocks
and resets exposed by the GCC hardware block.
endmenu
endif

View File

@@ -7,4 +7,9 @@ obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o
obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o
obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o
obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o
obj-$(CONFIG_CLK_QCOM_QCM2290) += clock-qcm2290.o
obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o
obj-$(CONFIG_CLK_QCOM_SM6115) += clock-sm6115.o
obj-$(CONFIG_CLK_QCOM_SM8250) += clock-sm8250.o
obj-$(CONFIG_CLK_QCOM_SM8550) += clock-sm8550.o
obj-$(CONFIG_CLK_QCOM_SM8650) += clock-sm8650.o

View File

@@ -31,7 +31,8 @@
#define BLSP1_AHB_CBCR 0x1008
/* Uart clock control registers */
#define BLSP1_UART2_BCR (0x3028)
#define BLSP1_UART1_APPS_CBCR (0x203C)
#define BLSP1_UART1_APPS_CMD_RCGR (0x2044)
#define BLSP1_UART2_APPS_CBCR (0x302C)
#define BLSP1_UART2_APPS_CMD_RCGR (0x3034)
@@ -52,7 +53,7 @@ static struct vote_clk gcc_blsp1_ahb_clk = {
};
/* SDHCI */
static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
static int apq8016_clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
{
int div = 15; /* 100MHz default */
@@ -70,20 +71,35 @@ static int clk_init_sdc(struct msm_clk_priv *priv, int slot, uint rate)
}
/* UART: 115200 */
int apq8016_clk_init_uart(phys_addr_t base)
int apq8016_clk_init_uart(phys_addr_t base, unsigned long id)
{
u32 cmd_rcgr, apps_cbcr;
switch (id) {
case GCC_BLSP1_UART1_APPS_CLK:
cmd_rcgr = BLSP1_UART1_APPS_CMD_RCGR;
apps_cbcr = BLSP1_UART1_APPS_CBCR;
break;
case GCC_BLSP1_UART2_APPS_CLK:
cmd_rcgr = BLSP1_UART2_APPS_CMD_RCGR;
apps_cbcr = BLSP1_UART2_APPS_CBCR;
break;
default:
return 0;
}
/* Enable AHB clock */
clk_enable_vote_clk(base, &gcc_blsp1_ahb_clk);
/* 7372800 uart block clock @ GPLL0 */
clk_rcg_set_rate_mnd(base, BLSP1_UART2_APPS_CMD_RCGR, 1, 144, 15625,
CFG_CLK_SRC_GPLL0, 16);
clk_rcg_set_rate_mnd(base, cmd_rcgr, 1, 144, 15625, CFG_CLK_SRC_GPLL0,
16);
/* Vote for gpll0 clock */
clk_enable_gpll0(base, &gpll0_vote_clk);
/* Enable core clk */
clk_enable_cbc(base + BLSP1_UART2_APPS_CBCR);
clk_enable_cbc(base + apps_cbcr);
return 0;
}
@@ -94,14 +110,13 @@ static ulong apq8016_clk_set_rate(struct clk *clk, ulong rate)
switch (clk->id) {
case GCC_SDCC1_APPS_CLK: /* SDC1 */
return clk_init_sdc(priv, 0, rate);
break;
return apq8016_clk_init_sdc(priv, 0, rate);
case GCC_SDCC2_APPS_CLK: /* SDC2 */
return clk_init_sdc(priv, 1, rate);
break;
return apq8016_clk_init_sdc(priv, 1, rate);
case GCC_BLSP1_UART1_APPS_CLK: /* UART1 */
case GCC_BLSP1_UART2_APPS_CLK: /* UART2 */
return apq8016_clk_init_uart(priv->base);
break;
apq8016_clk_init_uart(priv->base, clk->id);
return 7372800;
default:
return 0;
}

View File

@@ -21,7 +21,7 @@ static ulong ipq4019_clk_set_rate(struct clk *clk, ulong rate)
switch (clk->id) {
case GCC_BLSP1_UART1_APPS_CLK: /*UART1*/
/* This clock is already initialized by SBL1 */
return 0;
return 1843200;
default:
return -EINVAL;
}

View File

@@ -0,0 +1,192 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
* Clock drivers for Qualcomm qcm2290
*
* (C) Copyright 2024 Linaro Ltd.
*/
#include <clk-uclass.h>
#include <dm.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <linux/bug.h>
#include <linux/bitops.h>
#include <dt-bindings/clock/qcom,gcc-qcm2290.h>
#include "clock-qcom.h"
#define QUPV3_WRAP0_S4_CMD_RCGR 0x1f608
#define SDCC2_APPS_CLK_CMD_RCGR 0x1e00c
static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
F(7372800, CFG_CLK_SRC_GPLL0_AUX2, 1, 384, 15625),
F(14745600, CFG_CLK_SRC_GPLL0_AUX2, 1, 768, 15625),
F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
F(29491200, CFG_CLK_SRC_GPLL0_AUX2, 1, 1536, 15625),
F(32000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 8, 75),
F(48000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 4, 25),
F(64000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 16, 75),
F(75000000, CFG_CLK_SRC_GPLL0_AUX2, 4, 0, 0),
F(80000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 4, 15),
F(96000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 8, 25),
F(100000000, CFG_CLK_SRC_GPLL0_AUX2, 3, 0, 0),
F(102400000, CFG_CLK_SRC_GPLL0_AUX2, 1, 128, 375),
F(112000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 28, 75),
F(117964800, CFG_CLK_SRC_GPLL0_AUX2, 1, 6144, 15625),
F(120000000, CFG_CLK_SRC_GPLL0_AUX2, 2.5, 0, 0),
F(128000000, CFG_CLK_SRC_GPLL6, 3, 0, 0),
{}
};
static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
F(400000, CFG_CLK_SRC_CXO, 12, 1, 4),
F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
F(25000000, CFG_CLK_SRC_GPLL0_AUX2, 12, 0, 0),
F(50000000, CFG_CLK_SRC_GPLL0_AUX2, 6, 0, 0),
F(100000000, CFG_CLK_SRC_GPLL0_AUX2, 3, 0, 0),
F(202000000, CFG_CLK_SRC_GPLL7, 4, 0, 0), // 6.5, 1, 4
{}
};
static const struct pll_vote_clk gpll7_clk = {
.status = 0x7000,
.status_bit = BIT(31),
.ena_vote = 0x79000,
.vote_bit = BIT(7),
};
static const struct gate_clk qcm2290_clks[] = {
GATE_CLK(GCC_AHB2PHY_USB_CLK, 0x1d008, 0x00000001),
GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x1a084, 0x00000001),
GATE_CLK(GCC_QUPV3_WRAP0_CORE_2X_CLK, 0x7900c, 0x00000200),
GATE_CLK(GCC_QUPV3_WRAP0_CORE_CLK, 0x7900c, 0x00000100),
GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x7900c, 0x00000400),
GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x7900c, 0x00000800),
GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x7900c, 0x00001000),
GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x7900c, 0x00002000),
GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x7900c, 0x00004000),
GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x7900c, 0x00008000),
GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK, 0x7900c, 0x00000040),
GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK, 0x7900c, 0x00000080),
GATE_CLK(GCC_SDCC1_AHB_CLK, 0x38008, 0x00000001),
GATE_CLK(GCC_SDCC1_APPS_CLK, 0x38004, 0x00000001),
GATE_CLK(GCC_SDCC1_ICE_CORE_CLK, 0x3800c, 0x00000001),
GATE_CLK(GCC_SDCC2_AHB_CLK, 0x1e008, 0x00000001),
GATE_CLK(GCC_SDCC2_APPS_CLK, 0x1e004, 0x00000001),
GATE_CLK(GCC_SYS_NOC_CPUSS_AHB_CLK, 0x79004, 0x00000001),
GATE_CLK(GCC_SYS_NOC_USB3_PRIM_AXI_CLK, 0x1a080, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x1a010, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x1a018, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x1a014, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_CLKREF_CLK, 0x9f000, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x1a054, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x1a058, 0x00000001),
};
static ulong qcm2290_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
const struct freq_tbl *freq;
debug("%s: clk %s rate %lu\n", __func__, clk->dev->name, rate);
switch (clk->id) {
case GCC_QUPV3_WRAP0_S4_CLK: /*UART2*/
freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, QUPV3_WRAP0_S4_CMD_RCGR,
freq->pre_div, freq->m, freq->n, freq->src,
16);
return 0;
case GCC_SDCC2_APPS_CLK:
/* Enable GPLL7 so we can point SDCC2_APPS_CLK_SRC RCG at it */
clk_enable_gpll0(priv->base, &gpll7_clk);
freq = qcom_find_freq(ftbl_gcc_sdcc2_apps_clk_src, rate);
WARN(freq->src != CFG_CLK_SRC_GPLL7,
"SDCC2_APPS_CLK_SRC not set to GPLL7, requested rate %lu\n",
rate);
clk_rcg_set_rate_mnd(priv->base, SDCC2_APPS_CLK_CMD_RCGR,
freq->pre_div, freq->m, freq->n, freq->src,
8);
return freq->freq;
case GCC_SDCC1_APPS_CLK:
/* The firmware turns this on for us and always sets it to this rate */
return 384000000;
default:
return 0;
}
}
static int qcm2290_enable(struct clk *clk)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
if (priv->data->num_clks < clk->id) {
debug("%s: unknown clk id %lu\n", __func__, clk->id);
return 0;
}
debug("%s: clk %s\n", __func__, qcm2290_clks[clk->id].name);
switch (clk->id) {
case GCC_USB30_PRIM_MASTER_CLK:
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
qcom_gate_clk_en(priv, GCC_USB3_PRIM_CLKREF_CLK);
break;
}
qcom_gate_clk_en(priv, clk->id);
return 0;
}
static const struct qcom_reset_map qcm2290_gcc_resets[] = {
[GCC_CAMSS_OPE_BCR] = { 0x55000 },
[GCC_CAMSS_TFE_BCR] = { 0x52000 },
[GCC_CAMSS_TOP_BCR] = { 0x58000 },
[GCC_GPU_BCR] = { 0x36000 },
[GCC_MMSS_BCR] = { 0x17000 },
[GCC_PDM_BCR] = { 0x20000 },
[GCC_QUPV3_WRAPPER_0_BCR] = { 0x1f000 },
[GCC_QUSB2PHY_PRIM_BCR] = { 0x1c000 },
[GCC_SDCC1_BCR] = { 0x38000 },
[GCC_SDCC2_BCR] = { 0x1e000 },
[GCC_USB30_PRIM_BCR] = { 0x1a000 },
[GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x1b000 },
[GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x1b008 },
[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x1d000 },
[GCC_VCODEC0_BCR] = { 0x58094 },
[GCC_VENUS_BCR] = { 0x58078 },
[GCC_VIDEO_INTERFACE_BCR] = { 0x6e000 },
};
static const struct qcom_power_map qcm2290_gdscs[] = {
[GCC_USB30_PRIM_GDSC] = { 0x1a004 },
};
static struct msm_clk_data qcm2290_gcc_data = {
.resets = qcm2290_gcc_resets,
.num_resets = ARRAY_SIZE(qcm2290_gcc_resets),
.clks = qcm2290_clks,
.num_clks = ARRAY_SIZE(qcm2290_clks),
.power_domains = qcm2290_gdscs,
.num_power_domains = ARRAY_SIZE(qcm2290_gdscs),
.enable = qcm2290_enable,
.set_rate = qcm2290_set_rate,
};
static const struct udevice_id gcc_qcm2290_of_match[] = {
{
.compatible = "qcom,gcc-qcm2290",
.data = (ulong)&qcm2290_gcc_data,
},
{}
};
U_BOOT_DRIVER(gcc_qcm2290) = {
.name = "gcc_qcm2290",
.id = UCLASS_NOP,
.of_match = gcc_qcm2290_of_match,
.bind = qcom_cc_bind,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@@ -9,6 +9,11 @@
#define CFG_CLK_SRC_CXO (0 << 8)
#define CFG_CLK_SRC_GPLL0 (1 << 8)
#define CFG_CLK_SRC_GPLL0_AUX2 (2 << 8)
#define CFG_CLK_SRC_GPLL9 (2 << 8)
#define CFG_CLK_SRC_GPLL6 (4 << 8)
#define CFG_CLK_SRC_GPLL7 (3 << 8)
#define CFG_CLK_SRC_GPLL4 (5 << 8)
#define CFG_CLK_SRC_GPLL0_EVEN (6 << 8)
#define CFG_CLK_SRC_MASK (7 << 8)

View File

@@ -24,6 +24,7 @@
#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf018
#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf030
#define USB3_PRIM_PHY_AUX_CMD_RCGR 0xf05c
#define SDCC2_APPS_CLK_CMD_RCGR 0x1400c
static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
@@ -44,6 +45,17 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
{ }
};
static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
F(400000, CFG_CLK_SRC_CXO, 12, 1, 4),
F(9600000, CFG_CLK_SRC_CXO, 2, 0, 0),
F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
F(50000000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
F(201500000, CFG_CLK_SRC_GPLL4, 4, 0, 0),
{ }
};
static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
@@ -55,6 +67,11 @@ static ulong sdm845_clk_set_rate(struct clk *clk, ulong rate)
clk_rcg_set_rate_mnd(priv->base, SE9_UART_APPS_CMD_RCGR,
freq->pre_div, freq->m, freq->n, freq->src, 16);
return freq->freq;
case GCC_SDCC2_APPS_CLK:
freq = qcom_find_freq(ftbl_gcc_sdcc2_apps_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, SDCC2_APPS_CLK_CMD_RCGR,
freq->pre_div, freq->m, freq->n, freq->src, 8);
return freq->freq;
default:
return 0;
}

View File

@@ -0,0 +1,199 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
* Clock drivers for Qualcomm sm6115 (and sm4250/qrb4210)
*
* Copyright (c) 2024 Linaro Ltd.
*
*/
#include <clk-uclass.h>
#include <dm.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <linux/bug.h>
#include <dt-bindings/clock/qcom,gcc-sm6115.h>
#include "clock-qcom.h"
#define QUPV3_WRAP0_S4_CMD_RCGR 0x1f608
#define SDCC1_APPS_CLK_CMD_RCGR 0x38028
#define SDCC2_APPS_CLK_CMD_RCGR 0x1e00c
static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
F(7372800, CFG_CLK_SRC_GPLL0_AUX2, 1, 384, 15625),
F(14745600, CFG_CLK_SRC_GPLL0_AUX2, 1, 768, 15625),
F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
F(29491200, CFG_CLK_SRC_GPLL0_AUX2, 1, 1536, 15625),
F(32000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 8, 75),
F(48000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 4, 25),
F(64000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 16, 75),
F(75000000, CFG_CLK_SRC_GPLL0_AUX2, 4, 0, 0),
F(80000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 4, 15),
F(96000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 8, 25),
F(100000000, CFG_CLK_SRC_GPLL0_AUX2, 3, 0, 0),
F(102400000, CFG_CLK_SRC_GPLL0_AUX2, 1, 128, 375),
F(112000000, CFG_CLK_SRC_GPLL0_AUX2, 1, 28, 75),
F(117964800, CFG_CLK_SRC_GPLL0_AUX2, 1, 6144, 15625),
F(120000000, CFG_CLK_SRC_GPLL0_AUX2, 2.5, 0, 0),
F(128000000, CFG_CLK_SRC_GPLL6, 3, 0, 0),
{}
};
static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
F(400000, CFG_CLK_SRC_CXO, 12, 1, 4),
F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
F(25000000, CFG_CLK_SRC_GPLL0_AUX2, 12, 0, 0),
F(50000000, CFG_CLK_SRC_GPLL0_AUX2, 6, 0, 0),
F(100000000, CFG_CLK_SRC_GPLL0_AUX2, 3, 0, 0),
F(200000000, CFG_CLK_SRC_GPLL0, 3, 0, 0),
{}
};
static const struct pll_vote_clk gpll0_clk = {
.status = 0,
.status_bit = BIT(31),
.ena_vote = 0x79000,
.vote_bit = BIT(0),
};
static const struct gate_clk sm6115_clks[] = {
GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x1a084, 0x00000001),
GATE_CLK(GCC_QUPV3_WRAP0_CORE_2X_CLK, 0x7900c, 0x00000200),
GATE_CLK(GCC_QUPV3_WRAP0_CORE_CLK, 0x7900c, 0x00000100),
GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x7900c, 0x00000400),
GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x7900c, 0x00000800),
GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x7900c, 0x00001000),
GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x7900c, 0x00002000),
GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x7900c, 0x00004000),
GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x7900c, 0x00008000),
GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK, 0x7900c, 0x00000040),
GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK, 0x7900c, 0x00000080),
GATE_CLK(GCC_SDCC1_AHB_CLK, 0x38008, 0x00000001),
GATE_CLK(GCC_SDCC1_APPS_CLK, 0x38004, 0x00000001),
GATE_CLK(GCC_SDCC1_ICE_CORE_CLK, 0x3800c, 0x00000001),
GATE_CLK(GCC_SDCC2_AHB_CLK, 0x1e008, 0x00000001),
GATE_CLK(GCC_SDCC2_APPS_CLK, 0x1e004, 0x00000001),
GATE_CLK(GCC_SYS_NOC_CPUSS_AHB_CLK, 0x79004, 0x00000001),
GATE_CLK(GCC_SYS_NOC_UFS_PHY_AXI_CLK, 0x45098, 0x00000001),
GATE_CLK(GCC_SYS_NOC_USB3_PRIM_AXI_CLK, 0x1a080, 0x00000001),
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x45014, 0x00000001),
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x45010, 0x00000001),
GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x45044, 0x00000001),
GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x45078, 0x00000001),
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x4501c, 0x00000001),
GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x45018, 0x00000001),
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x45040, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x1a010, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x1a018, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x1a014, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_CLKREF_CLK, 0x9f000, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x1a054, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x1a058, 0x00000001),
GATE_CLK(GCC_AHB2PHY_USB_CLK, 0x1d008, 0x00000001),
GATE_CLK(GCC_UFS_CLKREF_CLK, 0x8c000, 0x00000001),
};
static ulong sm6115_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
const struct freq_tbl *freq;
debug("%s: clk %s rate %lu\n", __func__, sm6115_clks[clk->id].name,
rate);
switch (clk->id) {
case GCC_QUPV3_WRAP0_S4_CLK: /*UART2*/
freq = qcom_find_freq(ftbl_gcc_qupv3_wrap0_s0_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, QUPV3_WRAP0_S4_CMD_RCGR,
freq->pre_div, freq->m, freq->n, freq->src,
16);
return 0;
case GCC_SDCC2_APPS_CLK:
/* Enable GPLL7 so we can point SDCC2_APPS_CLK_SRC RCG at it */
clk_enable_gpll0(priv->base, &gpll0_clk);
freq = qcom_find_freq(ftbl_gcc_sdcc2_apps_clk_src, rate);
WARN(freq->src != CFG_CLK_SRC_GPLL0,
"SDCC2_APPS_CLK_SRC not set to GPLL0, requested rate %lu\n",
rate);
clk_rcg_set_rate_mnd(priv->base, SDCC2_APPS_CLK_CMD_RCGR,
freq->pre_div, freq->m, freq->n, freq->src,
8);
return freq->freq;
case GCC_SDCC1_APPS_CLK:
/* The firmware turns this on for us and always sets it to this rate */
return 384000000;
default:
return rate;
}
}
static int sm6115_enable(struct clk *clk)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
if (priv->data->num_clks < clk->id) {
debug("%s: unknown clk id %lu\n", __func__, clk->id);
return 0;
}
debug("%s: clk %s\n", __func__, sm6115_clks[clk->id].name);
switch (clk->id) {
case GCC_USB30_PRIM_MASTER_CLK:
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
qcom_gate_clk_en(priv, GCC_USB3_PRIM_CLKREF_CLK);
break;
}
qcom_gate_clk_en(priv, clk->id);
return 0;
}
static const struct qcom_reset_map sm6115_gcc_resets[] = {
[GCC_QUSB2PHY_PRIM_BCR] = { 0x1c000 },
[GCC_QUSB2PHY_SEC_BCR] = { 0x1c004 },
[GCC_SDCC1_BCR] = { 0x38000 },
[GCC_SDCC2_BCR] = { 0x1e000 },
[GCC_UFS_PHY_BCR] = { 0x45000 },
[GCC_USB30_PRIM_BCR] = { 0x1a000 },
[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x1d000 },
[GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x1b008 },
[GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x1b000 },
[GCC_VCODEC0_BCR] = { 0x58094 },
[GCC_VENUS_BCR] = { 0x58078 },
[GCC_VIDEO_INTERFACE_BCR] = { 0x6e000 },
};
static const struct qcom_power_map sm6115_gdscs[] = {
[GCC_USB30_PRIM_GDSC] = { 0x1a004 },
};
static struct msm_clk_data sm6115_gcc_data = {
.resets = sm6115_gcc_resets,
.num_resets = ARRAY_SIZE(sm6115_gcc_resets),
.clks = sm6115_clks,
.num_clks = ARRAY_SIZE(sm6115_clks),
.power_domains = sm6115_gdscs,
.num_power_domains = ARRAY_SIZE(sm6115_gdscs),
.enable = sm6115_enable,
.set_rate = sm6115_set_rate,
};
static const struct udevice_id gcc_sm6115_of_match[] = {
{
.compatible = "qcom,gcc-sm6115",
.data = (ulong)&sm6115_gcc_data,
},
{}
};
U_BOOT_DRIVER(gcc_sm6115) = {
.name = "gcc_sm6115",
.id = UCLASS_NOP,
.of_match = gcc_sm6115_of_match,
.bind = qcom_cc_bind,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@@ -0,0 +1,282 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
* Clock drivers for Qualcomm sm8250
*
* (C) Copyright 2024 Linaro Ltd.
*/
#include <clk-uclass.h>
#include <dm.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <linux/bug.h>
#include <linux/bitops.h>
#include <dt-bindings/clock/qcom,gcc-sm8250.h>
#include "clock-qcom.h"
#define GCC_SE12_UART_RCG_REG 0x184D0
#define GCC_SDCC2_APPS_CLK_SRC_REG 0x1400c
#define APCS_GPLL0_ENA_VOTE 0x79000
#define APCS_GPLL9_STATUS 0x1c000
#define APCS_GPLLX_ENA_REG 0x52018
#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf020
#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf038
#define USB3_PRIM_PHY_AUX_CMD_RCGR 0xf064
static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s4_clk_src[] = {
F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
F(50000000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
{}
};
static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
F(400000, CFG_CLK_SRC_CXO, 12, 1, 4),
F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
F(50000000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
F(202000000, CFG_CLK_SRC_GPLL9, 4, 0, 0),
{}
};
static struct pll_vote_clk gpll9_vote_clk = {
.status = APCS_GPLL9_STATUS,
.status_bit = BIT(31),
.ena_vote = APCS_GPLLX_ENA_REG,
.vote_bit = BIT(9),
};
static ulong sm8250_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
const struct freq_tbl *freq;
if (clk->id < priv->data->num_clks)
debug("%s: %s, requested rate=%ld\n", __func__,
priv->data->clks[clk->id].name, rate);
switch (clk->id) {
case GCC_QUPV3_WRAP1_S4_CLK: /*UART2*/
freq = qcom_find_freq(ftbl_gcc_qupv3_wrap1_s4_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, GCC_SE12_UART_RCG_REG,
freq->pre_div, freq->m, freq->n, freq->src,
16);
return freq->freq;
case GCC_SDCC2_APPS_CLK:
/* Enable GPLL9 so that we can point SDCC2_APPS_CLK_SRC at it */
clk_enable_gpll0(priv->base, &gpll9_vote_clk);
freq = qcom_find_freq(ftbl_gcc_sdcc2_apps_clk_src, rate);
printf("%s: got freq %u\n", __func__, freq->freq);
WARN(freq->src != CFG_CLK_SRC_GPLL9,
"SDCC2_APPS_CLK_SRC not set to GPLL9, requested rate %lu\n",
rate);
clk_rcg_set_rate_mnd(priv->base, GCC_SDCC2_APPS_CLK_SRC_REG,
freq->pre_div, freq->m, freq->n,
CFG_CLK_SRC_GPLL9, 8);
return rate;
default:
return 0;
}
}
static const struct gate_clk sm8250_clks[] = {
GATE_CLK(GCC_AGGRE_UFS_CARD_AXI_CLK, 0x750cc, 0x00000001),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770cc, 0x00000001),
GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x0f080, 0x00000001),
GATE_CLK(GCC_AGGRE_USB3_SEC_AXI_CLK, 0x10080, 0x00000001),
GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x0f07c, 0x00000001),
GATE_CLK(GCC_CFG_NOC_USB3_SEC_AXI_CLK, 0x1007c, 0x00000001),
GATE_CLK(GCC_QMIP_CAMERA_NRT_AHB_CLK, 0x0b018, 0x00000001),
GATE_CLK(GCC_QMIP_CAMERA_RT_AHB_CLK, 0x0b01c, 0x00000001),
GATE_CLK(GCC_QMIP_DISP_AHB_CLK, 0x0b020, 0x00000001),
GATE_CLK(GCC_QMIP_VIDEO_CVP_AHB_CLK, 0x0b010, 0x00000001),
GATE_CLK(GCC_QMIP_VIDEO_VCODEC_AHB_CLK, 0x0b014, 0x00000001),
GATE_CLK(GCC_QUPV3_WRAP0_CORE_2X_CLK, 0x52008, 0x00000200),
GATE_CLK(GCC_QUPV3_WRAP0_CORE_CLK, 0x52008, 0x00000100),
GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x52008, 0x00000400),
GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x52008, 0x00000800),
GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x52008, 0x00001000),
GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x52008, 0x00002000),
GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x52008, 0x00004000),
GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x52008, 0x00008000),
GATE_CLK(GCC_QUPV3_WRAP0_S6_CLK, 0x52008, 0x00010000),
GATE_CLK(GCC_QUPV3_WRAP0_S7_CLK, 0x52008, 0x00020000),
GATE_CLK(GCC_QUPV3_WRAP1_CORE_2X_CLK, 0x52008, 0x00040000),
GATE_CLK(GCC_QUPV3_WRAP1_CORE_CLK, 0x52008, 0x00080000),
GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK, 0x52008, 0x00400000),
GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x52008, 0x00800000),
GATE_CLK(GCC_QUPV3_WRAP1_S2_CLK, 0x52008, 0x01000000),
GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK, 0x52008, 0x02000000),
GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x52008, 0x04000000),
GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x52008, 0x08000000),
GATE_CLK(GCC_QUPV3_WRAP2_CORE_2X_CLK, 0x52010, 0x00000008),
GATE_CLK(GCC_QUPV3_WRAP2_CORE_CLK, 0x52010, 0x00000001),
GATE_CLK(GCC_QUPV3_WRAP2_S0_CLK, 0x52010, 0x00000010),
GATE_CLK(GCC_QUPV3_WRAP2_S1_CLK, 0x52010, 0x00000020),
GATE_CLK(GCC_QUPV3_WRAP2_S2_CLK, 0x52010, 0x00000040),
GATE_CLK(GCC_QUPV3_WRAP2_S3_CLK, 0x52010, 0x00000080),
GATE_CLK(GCC_QUPV3_WRAP2_S4_CLK, 0x52010, 0x00000100),
GATE_CLK(GCC_QUPV3_WRAP2_S5_CLK, 0x52010, 0x00000200),
GATE_CLK(GCC_QUPV3_WRAP_0_M_AHB_CLK, 0x52008, 0x00000040),
GATE_CLK(GCC_QUPV3_WRAP_0_S_AHB_CLK, 0x52008, 0x00000080),
GATE_CLK(GCC_QUPV3_WRAP_1_M_AHB_CLK, 0x52008, 0x00100000),
GATE_CLK(GCC_QUPV3_WRAP_1_S_AHB_CLK, 0x52008, 0x00200000),
GATE_CLK(GCC_QUPV3_WRAP_2_M_AHB_CLK, 0x52010, 0x00000004),
GATE_CLK(GCC_QUPV3_WRAP_2_S_AHB_CLK, 0x52010, 0x00000002),
GATE_CLK(GCC_SDCC2_AHB_CLK, 0x14008, 0x00000001),
GATE_CLK(GCC_SDCC2_APPS_CLK, 0x14004, 0x00000001),
GATE_CLK(GCC_SDCC4_AHB_CLK, 0x16008, 0x00000001),
GATE_CLK(GCC_SDCC4_APPS_CLK, 0x16004, 0x00000001),
GATE_CLK(GCC_UFS_CARD_AHB_CLK, 0x75018, 0x00000001),
GATE_CLK(GCC_UFS_CARD_AXI_CLK, 0x75010, 0x00000001),
GATE_CLK(GCC_UFS_CARD_ICE_CORE_CLK, 0x75064, 0x00000001),
GATE_CLK(GCC_UFS_CARD_PHY_AUX_CLK, 0x7509c, 0x00000001),
GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_0_CLK, 0x75020, 0x00000001),
GATE_CLK(GCC_UFS_CARD_RX_SYMBOL_1_CLK, 0x750b8, 0x00000001),
GATE_CLK(GCC_UFS_CARD_TX_SYMBOL_0_CLK, 0x7501c, 0x00000001),
GATE_CLK(GCC_UFS_CARD_UNIPRO_CORE_CLK, 0x7505c, 0x00000001),
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77018, 0x00000001),
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77010, 0x00000001),
GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77064, 0x00000001),
GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x7709c, 0x00000001),
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x77020, 0x00000001),
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770b8, 0x00000001),
GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x7701c, 0x00000001),
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x7705c, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x0f010, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x0f01c, 0x00000001),
GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x0f018, 0x00000001),
GATE_CLK(GCC_USB30_SEC_MASTER_CLK, 0x10010, 0x00000001),
GATE_CLK(GCC_USB30_SEC_MOCK_UTMI_CLK, 0x1001c, 0x00000001),
GATE_CLK(GCC_USB30_SEC_SLEEP_CLK, 0x10018, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0x0f054, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x0f058, 0x00000001),
GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x0f05c, 0x00000001),
GATE_CLK(GCC_USB3_SEC_CLKREF_EN, 0x8c010, 0x00000001),
GATE_CLK(GCC_USB3_SEC_PHY_AUX_CLK, 0x10054, 0x00000001),
GATE_CLK(GCC_USB3_SEC_PHY_COM_AUX_CLK, 0x10058, 0x00000001),
GATE_CLK(GCC_USB3_SEC_PHY_PIPE_CLK, 0x1005c, 0x00000001),
};
static int sm8250_enable(struct clk *clk)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
if (priv->data->num_clks < clk->id) {
debug("%s: unknown clk id %lu\n", __func__, clk->id);
return 0;
}
debug("%s: clk %s\n", __func__, sm8250_clks[clk->id].name);
switch (clk->id) {
case GCC_USB30_PRIM_MASTER_CLK:
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_AUX_CLK);
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
break;
case GCC_USB30_SEC_MASTER_CLK:
qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_AUX_CLK);
qcom_gate_clk_en(priv, GCC_USB3_SEC_PHY_COM_AUX_CLK);
break;
}
qcom_gate_clk_en(priv, clk->id);
return 0;
}
static const struct qcom_reset_map sm8250_gcc_resets[] = {
[GCC_GPU_BCR] = { 0x71000 },
[GCC_MMSS_BCR] = { 0xb000 },
[GCC_NPU_BWMON_BCR] = { 0x73000 },
[GCC_NPU_BCR] = { 0x4d000 },
[GCC_PCIE_0_BCR] = { 0x6b000 },
[GCC_PCIE_0_LINK_DOWN_BCR] = { 0x6c014 },
[GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0x6c020 },
[GCC_PCIE_0_PHY_BCR] = { 0x6c01c },
[GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0x6c028 },
[GCC_PCIE_1_BCR] = { 0x8d000 },
[GCC_PCIE_1_LINK_DOWN_BCR] = { 0x8e014 },
[GCC_PCIE_1_NOCSR_COM_PHY_BCR] = { 0x8e020 },
[GCC_PCIE_1_PHY_BCR] = { 0x8e01c },
[GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0x8e000 },
[GCC_PCIE_2_BCR] = { 0x6000 },
[GCC_PCIE_2_LINK_DOWN_BCR] = { 0x1f014 },
[GCC_PCIE_2_NOCSR_COM_PHY_BCR] = { 0x1f020 },
[GCC_PCIE_2_PHY_BCR] = { 0x1f01c },
[GCC_PCIE_2_PHY_NOCSR_COM_PHY_BCR] = { 0x1f028 },
[GCC_PCIE_PHY_BCR] = { 0x6f000 },
[GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x6f00c },
[GCC_PCIE_PHY_COM_BCR] = { 0x6f010 },
[GCC_PDM_BCR] = { 0x33000 },
[GCC_PRNG_BCR] = { 0x34000 },
[GCC_QUPV3_WRAPPER_0_BCR] = { 0x17000 },
[GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 },
[GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 },
[GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
[GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
[GCC_SDCC2_BCR] = { 0x14000 },
[GCC_SDCC4_BCR] = { 0x16000 },
[GCC_TSIF_BCR] = { 0x36000 },
[GCC_UFS_CARD_BCR] = { 0x75000 },
[GCC_UFS_PHY_BCR] = { 0x77000 },
[GCC_USB30_PRIM_BCR] = { 0xf000 },
[GCC_USB30_SEC_BCR] = { 0x10000 },
[GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 },
[GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 },
[GCC_USB3_PHY_PRIM_BCR] = { 0x50000 },
[GCC_USB3_PHY_SEC_BCR] = { 0x5000c },
[GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 },
[GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 },
[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
};
static const struct qcom_power_map sm8250_gdscs[] = {
[PCIE_0_GDSC] = { 0x6b004 }, [PCIE_1_GDSC] = { 0x8d004 },
[PCIE_2_GDSC] = { 0x6004 }, [UFS_CARD_GDSC] = { 0x75004 },
[UFS_PHY_GDSC] = { 0x77004 }, [USB30_PRIM_GDSC] = { 0xf004 },
[USB30_SEC_GDSC] = { 0x10004 },
};
static struct msm_clk_data qcs404_gcc_data = {
.resets = sm8250_gcc_resets,
.num_resets = ARRAY_SIZE(sm8250_gcc_resets),
.clks = sm8250_clks,
.num_clks = ARRAY_SIZE(sm8250_clks),
.power_domains = sm8250_gdscs,
.num_power_domains = ARRAY_SIZE(sm8250_gdscs),
.enable = sm8250_enable,
.set_rate = sm8250_set_rate,
};
static const struct udevice_id gcc_sm8250_of_match[] = {
{
.compatible = "qcom,gcc-sm8250",
.data = (ulong)&qcs404_gcc_data,
},
{}
};
U_BOOT_DRIVER(gcc_sm8250) = {
.name = "gcc_sm8250",
.id = UCLASS_NOP,
.of_match = gcc_sm8250_of_match,
.bind = qcom_cc_bind,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@@ -0,0 +1,335 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
* Clock drivers for Qualcomm sm8550
*
* (C) Copyright 2024 Linaro Ltd.
*/
#include <clk-uclass.h>
#include <dm.h>
#include <linux/delay.h>
#include <errno.h>
#include <asm/io.h>
#include <linux/bug.h>
#include <linux/bitops.h>
#include <dt-bindings/clock/qcom,sm8550-gcc.h>
#include <dt-bindings/clock/qcom,sm8550-tcsr.h>
#include "clock-qcom.h"
/* On-board TCXO, TOFIX get from DT */
#define TCXO_RATE 38400000
/* bi_tcxo_div2 divided after RPMh output */
#define TCXO_DIV2_RATE (TCXO_RATE / 2)
static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s2_clk_src[] = {
F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
F(51200000, CFG_CLK_SRC_GPLL0_EVEN, 1, 64, 375),
F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
{ }
};
static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
F(400000, CFG_CLK_SRC_CXO, 12, 1, 4),
F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
F(37500000, CFG_CLK_SRC_GPLL0_EVEN, 8, 0, 0),
F(50000000, CFG_CLK_SRC_GPLL0_EVEN, 6, 0, 0),
F(100000000, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0),
/* TOFIX F(202000000, CFG_CLK_SRC_GPLL9, 4, 0, 0), */
{ }
};
static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
F(66666667, CFG_CLK_SRC_GPLL0_EVEN, 4.5, 0, 0),
F(133333333, CFG_CLK_SRC_GPLL0, 4.5, 0, 0),
F(200000000, CFG_CLK_SRC_GPLL0, 3, 0, 0),
F(240000000, CFG_CLK_SRC_GPLL0, 2.5, 0, 0),
{ }
};
static ulong sm8550_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
const struct freq_tbl *freq;
switch (clk->id) {
case GCC_QUPV3_WRAP1_S7_CLK: /* UART7 */
freq = qcom_find_freq(ftbl_gcc_qupv3_wrap1_s2_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, 0x18898,
freq->pre_div, freq->m, freq->n, freq->src, 16);
return freq->freq;
case GCC_SDCC2_APPS_CLK:
freq = qcom_find_freq(ftbl_gcc_sdcc2_apps_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, 0x14018,
freq->pre_div, freq->m, freq->n, freq->src, 8);
return freq->freq;
case GCC_USB30_PRIM_MASTER_CLK:
freq = qcom_find_freq(ftbl_gcc_usb30_prim_master_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, 0x3902c,
freq->pre_div, freq->m, freq->n, freq->src, 8);
return freq->freq;
case GCC_USB30_PRIM_MOCK_UTMI_CLK:
clk_rcg_set_rate(priv->base, 0x39044, 0, 0);
return TCXO_DIV2_RATE;
case GCC_USB3_PRIM_PHY_AUX_CLK_SRC:
clk_rcg_set_rate(priv->base, 0x39070, 0, 0);
return TCXO_DIV2_RATE;
default:
return 0;
}
}
static const struct gate_clk sm8550_clks[] = {
GATE_CLK(GCC_AGGRE_NOC_PCIE_AXI_CLK, 0x52000, BIT(12)),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770e4, BIT(0)),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK, 0x770e4, BIT(1)),
GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x3908c, BIT(0)),
GATE_CLK(GCC_CNOC_PCIE_SF_AXI_CLK, 0x52008, BIT(6)),
GATE_CLK(GCC_DDRSS_GPU_AXI_CLK, 0x71154, BIT(0)),
GATE_CLK(GCC_DDRSS_PCIE_SF_QTB_CLK, 0x52000, BIT(19)),
GATE_CLK(GCC_PCIE_0_AUX_CLK, 0x52008, BIT(3)),
GATE_CLK(GCC_PCIE_0_CFG_AHB_CLK, 0x52008, BIT(2)),
GATE_CLK(GCC_PCIE_0_MSTR_AXI_CLK, 0x52008, BIT(1)),
GATE_CLK(GCC_PCIE_0_PHY_RCHNG_CLK, 0x52000, BIT(22)),
GATE_CLK(GCC_PCIE_0_PIPE_CLK, 0x52008, BIT(4)),
GATE_CLK(GCC_PCIE_0_SLV_AXI_CLK, 0x52008, BIT(0)),
GATE_CLK(GCC_PCIE_0_SLV_Q2A_AXI_CLK, 0x52008, BIT(5)),
GATE_CLK(GCC_PCIE_1_AUX_CLK, 0x52000, BIT(29)),
GATE_CLK(GCC_PCIE_1_CFG_AHB_CLK, 0x52000, BIT(28)),
GATE_CLK(GCC_PCIE_1_MSTR_AXI_CLK, 0x52000, BIT(27)),
GATE_CLK(GCC_PCIE_1_PHY_AUX_CLK, 0x52000, BIT(24)),
GATE_CLK(GCC_PCIE_1_PHY_RCHNG_CLK, 0x52000, BIT(23)),
GATE_CLK(GCC_PCIE_1_PIPE_CLK, 0x52000, BIT(30)),
GATE_CLK(GCC_PCIE_1_SLV_AXI_CLK, 0x52000, BIT(26)),
GATE_CLK(GCC_PCIE_1_SLV_Q2A_AXI_CLK, 0x52000, BIT(25)),
GATE_CLK(GCC_QUPV3_I2C_CORE_CLK, 0x52008, BIT(8)),
GATE_CLK(GCC_QUPV3_I2C_S0_CLK, 0x52008, BIT(10)),
GATE_CLK(GCC_QUPV3_I2C_S1_CLK, 0x52008, BIT(11)),
GATE_CLK(GCC_QUPV3_I2C_S2_CLK, 0x52008, BIT(12)),
GATE_CLK(GCC_QUPV3_I2C_S3_CLK, 0x52008, BIT(13)),
GATE_CLK(GCC_QUPV3_I2C_S4_CLK, 0x52008, BIT(14)),
GATE_CLK(GCC_QUPV3_I2C_S5_CLK, 0x52008, BIT(15)),
GATE_CLK(GCC_QUPV3_I2C_S6_CLK, 0x52008, BIT(16)),
GATE_CLK(GCC_QUPV3_I2C_S7_CLK, 0x52008, BIT(17)),
GATE_CLK(GCC_QUPV3_I2C_S8_CLK, 0x52010, BIT(14)),
GATE_CLK(GCC_QUPV3_I2C_S9_CLK, 0x52010, BIT(15)),
GATE_CLK(GCC_QUPV3_I2C_S_AHB_CLK, 0x52008, BIT(7)),
GATE_CLK(GCC_QUPV3_WRAP1_CORE_2X_CLK, 0x52008, BIT(18)),
GATE_CLK(GCC_QUPV3_WRAP1_CORE_CLK, 0x52008, BIT(19)),
GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK, 0x52008, BIT(22)),
GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x52008, BIT(23)),
GATE_CLK(GCC_QUPV3_WRAP1_S2_CLK, 0x52008, BIT(24)),
GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK, 0x52008, BIT(25)),
GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x52008, BIT(26)),
GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x52008, BIT(27)),
GATE_CLK(GCC_QUPV3_WRAP1_S6_CLK, 0x52008, BIT(28)),
GATE_CLK(GCC_QUPV3_WRAP1_S7_CLK, 0x52010, BIT(16)),
GATE_CLK(GCC_QUPV3_WRAP2_CORE_2X_CLK, 0x52010, BIT(3)),
GATE_CLK(GCC_QUPV3_WRAP2_CORE_CLK, 0x52010, BIT(0)),
GATE_CLK(GCC_QUPV3_WRAP2_S0_CLK, 0x52010, BIT(4)),
GATE_CLK(GCC_QUPV3_WRAP2_S1_CLK, 0x52010, BIT(5)),
GATE_CLK(GCC_QUPV3_WRAP2_S2_CLK, 0x52010, BIT(6)),
GATE_CLK(GCC_QUPV3_WRAP2_S3_CLK, 0x52010, BIT(7)),
GATE_CLK(GCC_QUPV3_WRAP2_S4_CLK, 0x52010, BIT(8)),
GATE_CLK(GCC_QUPV3_WRAP2_S5_CLK, 0x52010, BIT(9)),
GATE_CLK(GCC_QUPV3_WRAP2_S6_CLK, 0x52010, BIT(10)),
GATE_CLK(GCC_QUPV3_WRAP2_S7_CLK, 0x52010, BIT(17)),
GATE_CLK(GCC_QUPV3_WRAP_1_M_AHB_CLK, 0x52008, BIT(20)),
GATE_CLK(GCC_QUPV3_WRAP_1_S_AHB_CLK, 0x52008, BIT(21)),
GATE_CLK(GCC_QUPV3_WRAP_2_M_AHB_CLK, 0x52010, BIT(2)),
GATE_CLK(GCC_QUPV3_WRAP_2_S_AHB_CLK, 0x52010, BIT(1)),
GATE_CLK(GCC_SDCC2_AHB_CLK, 0x14010, BIT(0)),
GATE_CLK(GCC_SDCC2_APPS_CLK, 0x14004, BIT(0)),
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77024, BIT(0)),
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77018, BIT(0)),
GATE_CLK(GCC_UFS_PHY_AXI_HW_CTL_CLK, 0x77018, BIT(1)),
GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77074, BIT(0)),
GATE_CLK(GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK, 0x77074, BIT(1)),
GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x770b0, BIT(0)),
GATE_CLK(GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK, 0x770b0, BIT(1)),
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x7702c, BIT(0)),
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770cc, BIT(0)),
GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77028, BIT(0)),
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77068, BIT(0)),
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK, 0x77068, BIT(1)),
GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x39018, BIT(0)),
GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x39028, BIT(0)),
GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x39024, BIT(0)),
GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0x39060, BIT(0)),
GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x39064, BIT(0)),
GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x39068, BIT(0)),
};
static int sm8550_enable(struct clk *clk)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
switch (clk->id) {
case GCC_AGGRE_USB3_PRIM_AXI_CLK:
qcom_gate_clk_en(priv, GCC_USB30_PRIM_MASTER_CLK);
fallthrough;
case GCC_USB30_PRIM_MASTER_CLK:
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_AUX_CLK);
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
break;
}
qcom_gate_clk_en(priv, clk->id);
return 0;
}
static const struct qcom_reset_map sm8550_gcc_resets[] = {
[GCC_CAMERA_BCR] = { 0x26000 },
[GCC_DISPLAY_BCR] = { 0x27000 },
[GCC_GPU_BCR] = { 0x71000 },
[GCC_PCIE_0_BCR] = { 0x6b000 },
[GCC_PCIE_0_LINK_DOWN_BCR] = { 0x6c014 },
[GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0x6c020 },
[GCC_PCIE_0_PHY_BCR] = { 0x6c01c },
[GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0x6c028 },
[GCC_PCIE_1_BCR] = { 0x8d000 },
[GCC_PCIE_1_LINK_DOWN_BCR] = { 0x8e014 },
[GCC_PCIE_1_NOCSR_COM_PHY_BCR] = { 0x8e020 },
[GCC_PCIE_1_PHY_BCR] = { 0x8e01c },
[GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0x8e024 },
[GCC_PCIE_PHY_BCR] = { 0x6f000 },
[GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x6f00c },
[GCC_PCIE_PHY_COM_BCR] = { 0x6f010 },
[GCC_PDM_BCR] = { 0x33000 },
[GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 },
[GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 },
[GCC_QUPV3_WRAPPER_I2C_BCR] = { 0x17000 },
[GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
[GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
[GCC_SDCC2_BCR] = { 0x14000 },
[GCC_SDCC4_BCR] = { 0x16000 },
[GCC_UFS_PHY_BCR] = { 0x77000 },
[GCC_USB30_PRIM_BCR] = { 0x39000 },
[GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 },
[GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 },
[GCC_USB3_PHY_PRIM_BCR] = { 0x50000 },
[GCC_USB3_PHY_SEC_BCR] = { 0x5000c },
[GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 },
[GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 },
[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 },
[GCC_VIDEO_AXI0_CLK_ARES] = { 0x32018, 2 },
[GCC_VIDEO_AXI1_CLK_ARES] = { 0x32024, 2 },
[GCC_VIDEO_BCR] = { 0x32000 },
};
static const struct qcom_power_map sm8550_gdscs[] = {
[PCIE_0_GDSC] = { 0x6b004 },
[PCIE_0_PHY_GDSC] = { 0x6c000 },
[PCIE_1_GDSC] = { 0x8d004 },
[PCIE_1_PHY_GDSC] = { 0x8e000 },
[UFS_PHY_GDSC] = { 0x77004 },
[UFS_MEM_PHY_GDSC] = { 0x9e000 },
[USB30_PRIM_GDSC] = { 0x39004 },
[USB3_PHY_GDSC] = { 0x50018 },
};
static struct msm_clk_data sm8550_gcc_data = {
.resets = sm8550_gcc_resets,
.num_resets = ARRAY_SIZE(sm8550_gcc_resets),
.clks = sm8550_clks,
.num_clks = ARRAY_SIZE(sm8550_clks),
.power_domains = sm8550_gdscs,
.num_power_domains = ARRAY_SIZE(sm8550_gdscs),
.enable = sm8550_enable,
.set_rate = sm8550_set_rate,
};
static const struct udevice_id gcc_sm8550_of_match[] = {
{
.compatible = "qcom,sm8550-gcc",
.data = (ulong)&sm8550_gcc_data,
},
{ }
};
U_BOOT_DRIVER(gcc_sm8550) = {
.name = "gcc_sm8550",
.id = UCLASS_NOP,
.of_match = gcc_sm8550_of_match,
.bind = qcom_cc_bind,
.flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
};
/* TCSRCC */
static const struct gate_clk sm8550_tcsr_clks[] = {
GATE_CLK(TCSR_PCIE_0_CLKREF_EN, 0x15100, BIT(0)),
GATE_CLK(TCSR_PCIE_1_CLKREF_EN, 0x15114, BIT(0)),
GATE_CLK(TCSR_UFS_CLKREF_EN, 0x15110, BIT(0)),
GATE_CLK(TCSR_UFS_PAD_CLKREF_EN, 0x15104, BIT(0)),
GATE_CLK(TCSR_USB2_CLKREF_EN, 0x15118, BIT(0)),
GATE_CLK(TCSR_USB3_CLKREF_EN, 0x15108, BIT(0)),
};
static struct msm_clk_data sm8550_tcsrcc_data = {
.clks = sm8550_tcsr_clks,
.num_clks = ARRAY_SIZE(sm8550_tcsr_clks),
};
static int tcsrcc_sm8550_clk_enable(struct clk *clk)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
qcom_gate_clk_en(priv, clk->id);
return 0;
}
static ulong tcsrcc_sm8550_clk_get_rate(struct clk *clk)
{
return TCXO_RATE;
}
static int tcsrcc_sm8550_clk_probe(struct udevice *dev)
{
struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(dev);
struct msm_clk_priv *priv = dev_get_priv(dev);
priv->base = dev_read_addr(dev);
if (priv->base == FDT_ADDR_T_NONE)
return -EINVAL;
priv->data = data;
return 0;
}
static struct clk_ops tcsrcc_sm8550_clk_ops = {
.enable = tcsrcc_sm8550_clk_enable,
.get_rate = tcsrcc_sm8550_clk_get_rate,
};
static const struct udevice_id tcsrcc_sm8550_of_match[] = {
{
.compatible = "qcom,sm8550-tcsr",
.data = (ulong)&sm8550_tcsrcc_data,
},
{ }
};
U_BOOT_DRIVER(tcsrcc_sm8550) = {
.name = "tcsrcc_sm8550",
.id = UCLASS_CLK,
.of_match = tcsrcc_sm8550_of_match,
.ops = &tcsrcc_sm8550_clk_ops,
.priv_auto = sizeof(struct msm_clk_priv),
.probe = tcsrcc_sm8550_clk_probe,
.flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
};

View File

@@ -0,0 +1,332 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
* Clock drivers for Qualcomm sm8650
*
* (C) Copyright 2024 Linaro Ltd.
*/
#include <clk-uclass.h>
#include <dm.h>
#include <linux/delay.h>
#include <errno.h>
#include <asm/io.h>
#include <linux/bug.h>
#include <linux/bitops.h>
#include <dt-bindings/clock/qcom,sm8650-gcc.h>
#include <dt-bindings/clock/qcom,sm8650-tcsr.h>
#include "clock-qcom.h"
/* On-board TCXO, TOFIX get from DT */
#define TCXO_RATE 38400000
/* bi_tcxo_div2 divided after RPMh output */
#define TCXO_DIV2_RATE (TCXO_RATE / 2)
static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s3_clk_src[] = {
F(7372800, CFG_CLK_SRC_GPLL0_EVEN, 1, 384, 15625),
F(14745600, CFG_CLK_SRC_GPLL0_EVEN, 1, 768, 15625),
F(19200000, CFG_CLK_SRC_CXO, 1, 0, 0),
F(29491200, CFG_CLK_SRC_GPLL0_EVEN, 1, 1536, 15625),
F(32000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 75),
F(48000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 25),
F(64000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 16, 75),
F(75000000, CFG_CLK_SRC_GPLL0_EVEN, 4, 0, 0),
F(80000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 4, 15),
F(96000000, CFG_CLK_SRC_GPLL0_EVEN, 1, 8, 25),
F(100000000, CFG_CLK_SRC_GPLL0, 6, 0, 0),
{ }
};
static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
F(400000, CFG_CLK_SRC_CXO, 12, 1, 4),
F(25000000, CFG_CLK_SRC_GPLL0_EVEN, 12, 0, 0),
F(100000000, CFG_CLK_SRC_GPLL0_EVEN, 3, 0, 0),
/* TOFIX F(202000000, CFG_CLK_SRC_GPLL9, 4, 0, 0), */
{ }
};
static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
F(66666667, CFG_CLK_SRC_GPLL0_EVEN, 4.5, 0, 0),
F(133333333, CFG_CLK_SRC_GPLL0, 4.5, 0, 0),
F(200000000, CFG_CLK_SRC_GPLL0, 3, 0, 0),
F(240000000, CFG_CLK_SRC_GPLL0, 2.5, 0, 0),
{ }
};
static ulong sm8650_set_rate(struct clk *clk, ulong rate)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
const struct freq_tbl *freq;
switch (clk->id) {
case GCC_QUPV3_WRAP2_S7_CLK: /* UART15 */
freq = qcom_find_freq(ftbl_gcc_qupv3_wrap1_s3_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, 0x1e898,
freq->pre_div, freq->m, freq->n, freq->src, 16);
return freq->freq;
case GCC_SDCC2_APPS_CLK:
freq = qcom_find_freq(ftbl_gcc_sdcc2_apps_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, 0x14018,
freq->pre_div, freq->m, freq->n, freq->src, 8);
return freq->freq;
case GCC_USB30_PRIM_MASTER_CLK:
freq = qcom_find_freq(ftbl_gcc_usb30_prim_master_clk_src, rate);
clk_rcg_set_rate_mnd(priv->base, 0x3902c,
freq->pre_div, freq->m, freq->n, freq->src, 8);
return freq->freq;
case GCC_USB30_PRIM_MOCK_UTMI_CLK:
clk_rcg_set_rate(priv->base, 0x39044, 0, 0);
return TCXO_DIV2_RATE;
case GCC_USB3_PRIM_PHY_AUX_CLK_SRC:
clk_rcg_set_rate(priv->base, 0x39070, 0, 0);
return TCXO_DIV2_RATE;
default:
return 0;
}
}
static const struct gate_clk sm8650_clks[] = {
GATE_CLK(GCC_AGGRE_NOC_PCIE_AXI_CLK, 0x52000, BIT(12)),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770e4, BIT(0)),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK, 0x770e4, BIT(1)),
GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x3908c, BIT(0)),
GATE_CLK(GCC_CNOC_PCIE_SF_AXI_CLK, 0x52008, BIT(6)),
GATE_CLK(GCC_DDRSS_GPU_AXI_CLK, 0x71154, BIT(0)),
GATE_CLK(GCC_DDRSS_PCIE_SF_QTB_CLK, 0x52000, BIT(19)),
GATE_CLK(GCC_PCIE_0_AUX_CLK, 0x52008, BIT(3)),
GATE_CLK(GCC_PCIE_0_CFG_AHB_CLK, 0x52008, BIT(2)),
GATE_CLK(GCC_PCIE_0_MSTR_AXI_CLK, 0x52008, BIT(1)),
GATE_CLK(GCC_PCIE_0_PHY_RCHNG_CLK, 0x52000, BIT(22)),
GATE_CLK(GCC_PCIE_0_PIPE_CLK, 0x52008, BIT(4)),
GATE_CLK(GCC_PCIE_0_SLV_AXI_CLK, 0x52008, BIT(0)),
GATE_CLK(GCC_PCIE_0_SLV_Q2A_AXI_CLK, 0x52008, BIT(5)),
GATE_CLK(GCC_PCIE_1_AUX_CLK, 0x52000, BIT(29)),
GATE_CLK(GCC_PCIE_1_CFG_AHB_CLK, 0x52000, BIT(28)),
GATE_CLK(GCC_PCIE_1_MSTR_AXI_CLK, 0x52000, BIT(27)),
GATE_CLK(GCC_PCIE_1_PHY_AUX_CLK, 0x52000, BIT(24)),
GATE_CLK(GCC_PCIE_1_PHY_RCHNG_CLK, 0x52000, BIT(23)),
GATE_CLK(GCC_PCIE_1_PIPE_CLK, 0x52000, BIT(30)),
GATE_CLK(GCC_PCIE_1_SLV_AXI_CLK, 0x52000, BIT(26)),
GATE_CLK(GCC_PCIE_1_SLV_Q2A_AXI_CLK, 0x52000, BIT(25)),
GATE_CLK(GCC_QUPV3_I2C_CORE_CLK, 0x52008, BIT(8)),
GATE_CLK(GCC_QUPV3_I2C_S0_CLK, 0x52008, BIT(10)),
GATE_CLK(GCC_QUPV3_I2C_S1_CLK, 0x52008, BIT(11)),
GATE_CLK(GCC_QUPV3_I2C_S2_CLK, 0x52008, BIT(12)),
GATE_CLK(GCC_QUPV3_I2C_S3_CLK, 0x52008, BIT(13)),
GATE_CLK(GCC_QUPV3_I2C_S4_CLK, 0x52008, BIT(14)),
GATE_CLK(GCC_QUPV3_I2C_S5_CLK, 0x52008, BIT(15)),
GATE_CLK(GCC_QUPV3_I2C_S6_CLK, 0x52008, BIT(16)),
GATE_CLK(GCC_QUPV3_I2C_S7_CLK, 0x52008, BIT(17)),
GATE_CLK(GCC_QUPV3_I2C_S8_CLK, 0x52010, BIT(14)),
GATE_CLK(GCC_QUPV3_I2C_S9_CLK, 0x52010, BIT(15)),
GATE_CLK(GCC_QUPV3_I2C_S_AHB_CLK, 0x52008, BIT(7)),
GATE_CLK(GCC_QUPV3_WRAP1_CORE_2X_CLK, 0x52008, BIT(18)),
GATE_CLK(GCC_QUPV3_WRAP1_CORE_CLK, 0x52008, BIT(19)),
GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK, 0x52008, BIT(22)),
GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x52008, BIT(23)),
GATE_CLK(GCC_QUPV3_WRAP1_S2_CLK, 0x52008, BIT(24)),
GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK, 0x52008, BIT(25)),
GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x52008, BIT(26)),
GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x52008, BIT(27)),
GATE_CLK(GCC_QUPV3_WRAP1_S6_CLK, 0x52008, BIT(28)),
GATE_CLK(GCC_QUPV3_WRAP1_S7_CLK, 0x52010, BIT(16)),
GATE_CLK(GCC_QUPV3_WRAP2_CORE_2X_CLK, 0x52010, BIT(3)),
GATE_CLK(GCC_QUPV3_WRAP2_CORE_CLK, 0x52010, BIT(0)),
GATE_CLK(GCC_QUPV3_WRAP2_S0_CLK, 0x52010, BIT(4)),
GATE_CLK(GCC_QUPV3_WRAP2_S1_CLK, 0x52010, BIT(5)),
GATE_CLK(GCC_QUPV3_WRAP2_S2_CLK, 0x52010, BIT(6)),
GATE_CLK(GCC_QUPV3_WRAP2_S3_CLK, 0x52010, BIT(7)),
GATE_CLK(GCC_QUPV3_WRAP2_S4_CLK, 0x52010, BIT(8)),
GATE_CLK(GCC_QUPV3_WRAP2_S5_CLK, 0x52010, BIT(9)),
GATE_CLK(GCC_QUPV3_WRAP2_S6_CLK, 0x52010, BIT(10)),
GATE_CLK(GCC_QUPV3_WRAP2_S7_CLK, 0x52010, BIT(17)),
GATE_CLK(GCC_QUPV3_WRAP_1_M_AHB_CLK, 0x52008, BIT(20)),
GATE_CLK(GCC_QUPV3_WRAP_1_S_AHB_CLK, 0x52008, BIT(21)),
GATE_CLK(GCC_QUPV3_WRAP_2_M_AHB_CLK, 0x52010, BIT(2)),
GATE_CLK(GCC_QUPV3_WRAP_2_S_AHB_CLK, 0x52010, BIT(1)),
GATE_CLK(GCC_SDCC2_AHB_CLK, 0x14010, BIT(0)),
GATE_CLK(GCC_SDCC2_APPS_CLK, 0x14004, BIT(0)),
GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x77024, BIT(0)),
GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x77018, BIT(0)),
GATE_CLK(GCC_UFS_PHY_AXI_HW_CTL_CLK, 0x77018, BIT(1)),
GATE_CLK(GCC_UFS_PHY_ICE_CORE_CLK, 0x77074, BIT(0)),
GATE_CLK(GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK, 0x77074, BIT(1)),
GATE_CLK(GCC_UFS_PHY_PHY_AUX_CLK, 0x770b0, BIT(0)),
GATE_CLK(GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK, 0x770b0, BIT(1)),
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_0_CLK, 0x7702c, BIT(0)),
GATE_CLK(GCC_UFS_PHY_RX_SYMBOL_1_CLK, 0x770cc, BIT(0)),
GATE_CLK(GCC_UFS_PHY_TX_SYMBOL_0_CLK, 0x77028, BIT(0)),
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x77068, BIT(0)),
GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK, 0x77068, BIT(1)),
GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x39018, BIT(0)),
GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x39028, BIT(0)),
GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x39024, BIT(0)),
GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0x39060, BIT(0)),
GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x39064, BIT(0)),
GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x39068, BIT(0)),
};
static int sm8650_enable(struct clk *clk)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
switch (clk->id) {
case GCC_AGGRE_USB3_PRIM_AXI_CLK:
qcom_gate_clk_en(priv, GCC_USB30_PRIM_MASTER_CLK);
fallthrough;
case GCC_USB30_PRIM_MASTER_CLK:
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_AUX_CLK);
qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK);
break;
}
qcom_gate_clk_en(priv, clk->id);
return 0;
}
static const struct qcom_reset_map sm8650_gcc_resets[] = {
[GCC_CAMERA_BCR] = { 0x26000 },
[GCC_DISPLAY_BCR] = { 0x27000 },
[GCC_GPU_BCR] = { 0x71000 },
[GCC_PCIE_0_BCR] = { 0x6b000 },
[GCC_PCIE_0_LINK_DOWN_BCR] = { 0x6c014 },
[GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0x6c020 },
[GCC_PCIE_0_PHY_BCR] = { 0x6c01c },
[GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0x6c028 },
[GCC_PCIE_1_BCR] = { 0x8d000 },
[GCC_PCIE_1_LINK_DOWN_BCR] = { 0x8e014 },
[GCC_PCIE_1_NOCSR_COM_PHY_BCR] = { 0x8e020 },
[GCC_PCIE_1_PHY_BCR] = { 0x8e01c },
[GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0x8e024 },
[GCC_PCIE_PHY_BCR] = { 0x6f000 },
[GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x6f00c },
[GCC_PCIE_PHY_COM_BCR] = { 0x6f010 },
[GCC_PDM_BCR] = { 0x33000 },
[GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 },
[GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 },
[GCC_QUPV3_WRAPPER_3_BCR] = { 0x19000 },
[GCC_QUPV3_WRAPPER_I2C_BCR] = { 0x17000 },
[GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
[GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
[GCC_SDCC2_BCR] = { 0x14000 },
[GCC_SDCC4_BCR] = { 0x16000 },
[GCC_UFS_PHY_BCR] = { 0x77000 },
[GCC_USB30_PRIM_BCR] = { 0x39000 },
[GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 },
[GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 },
[GCC_USB3_PHY_PRIM_BCR] = { 0x50000 },
[GCC_USB3_PHY_SEC_BCR] = { 0x5000c },
[GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 },
[GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 },
[GCC_VIDEO_AXI0_CLK_ARES] = { 0x32018, 2 },
[GCC_VIDEO_AXI1_CLK_ARES] = { 0x32024, 2 },
[GCC_VIDEO_BCR] = { 0x32000 },
};
static const struct qcom_power_map sm8650_gdscs[] = {
[PCIE_0_GDSC] = { 0x6b004 },
[PCIE_0_PHY_GDSC] = { 0x6c000 },
[PCIE_1_GDSC] = { 0x8d004 },
[PCIE_1_PHY_GDSC] = { 0x8e000 },
[UFS_PHY_GDSC] = { 0x77004 },
[UFS_MEM_PHY_GDSC] = { 0x9e000 },
[USB30_PRIM_GDSC] = { 0x39004 },
[USB3_PHY_GDSC] = { 0x50018 },
};
static struct msm_clk_data sm8650_gcc_data = {
.resets = sm8650_gcc_resets,
.num_resets = ARRAY_SIZE(sm8650_gcc_resets),
.clks = sm8650_clks,
.num_clks = ARRAY_SIZE(sm8650_clks),
.power_domains = sm8650_gdscs,
.num_power_domains = ARRAY_SIZE(sm8650_gdscs),
.enable = sm8650_enable,
.set_rate = sm8650_set_rate,
};
static const struct udevice_id gcc_sm8650_of_match[] = {
{
.compatible = "qcom,sm8650-gcc",
.data = (ulong)&sm8650_gcc_data,
},
{ }
};
U_BOOT_DRIVER(gcc_sm8650) = {
.name = "gcc_sm8650",
.id = UCLASS_NOP,
.of_match = gcc_sm8650_of_match,
.bind = qcom_cc_bind,
.flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
};
/* TCSRCC */
static const struct gate_clk sm8650_tcsr_clks[] = {
GATE_CLK(TCSR_PCIE_0_CLKREF_EN, 0x31100, BIT(0)),
GATE_CLK(TCSR_PCIE_1_CLKREF_EN, 0x31114, BIT(0)),
GATE_CLK(TCSR_UFS_CLKREF_EN, 0x31110, BIT(0)),
GATE_CLK(TCSR_UFS_PAD_CLKREF_EN, 0x31104, BIT(0)),
GATE_CLK(TCSR_USB2_CLKREF_EN, 0x31118, BIT(0)),
GATE_CLK(TCSR_USB3_CLKREF_EN, 0x31108, BIT(0)),
};
static struct msm_clk_data sm8650_tcsrcc_data = {
.clks = sm8650_tcsr_clks,
.num_clks = ARRAY_SIZE(sm8650_tcsr_clks),
};
static int tcsrcc_sm8650_clk_enable(struct clk *clk)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
qcom_gate_clk_en(priv, clk->id);
return 0;
}
static ulong tcsrcc_sm8650_clk_get_rate(struct clk *clk)
{
return TCXO_RATE;
}
static int tcsrcc_sm8650_clk_probe(struct udevice *dev)
{
struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(dev);
struct msm_clk_priv *priv = dev_get_priv(dev);
priv->base = dev_read_addr(dev);
if (priv->base == FDT_ADDR_T_NONE)
return -EINVAL;
priv->data = data;
return 0;
}
static struct clk_ops tcsrcc_sm8650_clk_ops = {
.enable = tcsrcc_sm8650_clk_enable,
.get_rate = tcsrcc_sm8650_clk_get_rate,
};
static const struct udevice_id tcsrcc_sm8650_of_match[] = {
{
.compatible = "qcom,sm8650-tcsr",
.data = (ulong)&sm8650_tcsrcc_data,
},
{ }
};
U_BOOT_DRIVER(tcsrcc_sm8650) = {
.name = "tcsrcc_sm8650",
.id = UCLASS_CLK,
.of_match = tcsrcc_sm8650_of_match,
.ops = &tcsrcc_sm8650_clk_ops,
.priv_auto = sizeof(struct msm_clk_priv),
.probe = tcsrcc_sm8650_clk_probe,
.flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
};

View File

@@ -35,6 +35,8 @@
#define REG_SUBTYPE_GPIOC_8CH 0xd
#define REG_SUBTYPE_GPIO_LV 0x10
#define REG_SUBTYPE_GPIO_MV 0x11
#define REG_SUBTYPE_GPIO_LV_VIN2 0x12
#define REG_SUBTYPE_GPIO_MV_VIN3 0x13
#define REG_STATUS 0x08
#define REG_STATUS_VAL_MASK 0x1
@@ -322,9 +324,20 @@ static int qcom_gpio_probe(struct udevice *dev)
return log_msg_ret("bad type", -ENXIO);
val = pmic_reg_read(plat->pmic, plat->pid + REG_SUBTYPE);
if (val != REG_SUBTYPE_GPIO_4CH && val != REG_SUBTYPE_GPIOC_4CH &&
val != REG_SUBTYPE_GPIO_LV && val != REG_SUBTYPE_GPIO_MV)
switch (val) {
case REG_SUBTYPE_GPIO_4CH:
case REG_SUBTYPE_GPIOC_4CH:
plat->lv_mv_type = false;
break;
case REG_SUBTYPE_GPIO_LV:
case REG_SUBTYPE_GPIO_MV:
case REG_SUBTYPE_GPIO_LV_VIN2:
case REG_SUBTYPE_GPIO_MV_VIN3:
plat->lv_mv_type = true;
break;
default:
return log_msg_ret("bad subtype", -ENXIO);
}
plat->lv_mv_type = val == REG_SUBTYPE_GPIO_LV ||
val == REG_SUBTYPE_GPIO_MV;
@@ -351,6 +364,9 @@ static const struct udevice_id qcom_gpio_ids[] = {
{ .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */
{ .compatible = "qcom,pm8998-gpio", .data = QCOM_PMIC_QUIRK_READONLY },
{ .compatible = "qcom,pms405-gpio" },
{ .compatible = "qcom,pm6125-gpio", .data = QCOM_PMIC_QUIRK_READONLY },
{ .compatible = "qcom,pm8150-gpio", .data = QCOM_PMIC_QUIRK_READONLY },
{ .compatible = "qcom,pm8550-gpio", .data = QCOM_PMIC_QUIRK_READONLY },
{ }
};

View File

@@ -638,6 +638,16 @@ config SYS_I2C_QUP
Technical Reference Manual, chapter "6.1 Qualcomm Universal
Peripherals Engine (QUP)".
config SYS_I2C_GENI
bool "Qualcomm Generic Interface (GENI) I2C controller"
depends on ARCH_SNAPDRAGON
help
Support for the Qualcomm Generic Interface (GENI) I2C interface.
The Generic Interface (GENI) is a firmware based Qualcomm Universal
Peripherals (QUP) Serial Engine (SE) Wrapper which can support multiple
bus protocols depending on the firmware type loaded at early boot time
based on system configuration.
config SYS_I2C_S3C24X0
bool "Samsung I2C driver"
depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5) && DM_I2C

View File

@@ -20,6 +20,7 @@ obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o
obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o
obj-$(CONFIG_SYS_I2C_DW_PCI) += designware_i2c_pci.o
obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o
obj-$(CONFIG_SYS_I2C_GENI) += geni_i2c.o
obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o
obj-$(CONFIG_SYS_I2C_INTEL) += intel_i2c.o
obj-$(CONFIG_SYS_I2C_IMX_LPI2C) += imx_lpi2c.o

575
drivers/i2c/geni_i2c.c Normal file
View File

@@ -0,0 +1,575 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2024, Linaro Limited
* Author: Neil Armstrong <neil.armstrong@linaro.org>
*
* Based on Linux driver: drivers/i2c/busses/i2c-qcom-geni.c
*/
#include <log.h>
#include <dm/device.h>
#include <dm/read.h>
#include <dm/device_compat.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <i2c.h>
#include <fdtdec.h>
#include <clk.h>
#include <reset.h>
#include <time.h>
#include <soc/qcom/geni-se.h>
#define SE_I2C_TX_TRANS_LEN 0x26c
#define SE_I2C_RX_TRANS_LEN 0x270
#define SE_I2C_SCL_COUNTERS 0x278
#define SE_I2C_ERR (M_CMD_OVERRUN_EN | M_ILLEGAL_CMD_EN | M_CMD_FAILURE_EN |\
M_GP_IRQ_1_EN | M_GP_IRQ_3_EN | M_GP_IRQ_4_EN)
#define SE_I2C_ABORT BIT(1)
/* M_CMD OP codes for I2C */
#define I2C_WRITE 0x1
#define I2C_READ 0x2
#define I2C_WRITE_READ 0x3
#define I2C_ADDR_ONLY 0x4
#define I2C_BUS_CLEAR 0x6
#define I2C_STOP_ON_BUS 0x7
/* M_CMD params for I2C */
#define PRE_CMD_DELAY BIT(0)
#define TIMESTAMP_BEFORE BIT(1)
#define STOP_STRETCH BIT(2)
#define TIMESTAMP_AFTER BIT(3)
#define POST_COMMAND_DELAY BIT(4)
#define IGNORE_ADD_NACK BIT(6)
#define READ_FINISHED_WITH_ACK BIT(7)
#define BYPASS_ADDR_PHASE BIT(8)
#define SLV_ADDR_MSK GENMASK(15, 9)
#define SLV_ADDR_SHFT 9
/* I2C SCL COUNTER fields */
#define HIGH_COUNTER_MSK GENMASK(29, 20)
#define HIGH_COUNTER_SHFT 20
#define LOW_COUNTER_MSK GENMASK(19, 10)
#define LOW_COUNTER_SHFT 10
#define CYCLE_COUNTER_MSK GENMASK(9, 0)
#define I2C_PACK_TX BIT(0)
#define I2C_PACK_RX BIT(1)
#define PACKING_BYTES_PW 4
#define GENI_I2C_IS_MASTER_HUB BIT(0)
#define I2C_TIMEOUT_MS 100
struct geni_i2c_clk_fld {
u32 clk_freq_out;
u8 clk_div;
u8 t_high_cnt;
u8 t_low_cnt;
u8 t_cycle_cnt;
};
struct geni_i2c_priv {
fdt_addr_t wrapper;
phys_addr_t base;
struct clk core;
struct clk se;
u32 tx_wm;
bool is_master_hub;
const struct geni_i2c_clk_fld *clk_fld;
};
/*
* Hardware uses the underlying formula to calculate time periods of
* SCL clock cycle. Firmware uses some additional cycles excluded from the
* below formula and it is confirmed that the time periods are within
* specification limits.
*
* time of high period of SCL: t_high = (t_high_cnt * clk_div) / source_clock
* time of low period of SCL: t_low = (t_low_cnt * clk_div) / source_clock
* time of full period of SCL: t_cycle = (t_cycle_cnt * clk_div) / source_clock
* clk_freq_out = t / t_cycle
* source_clock = 19.2 MHz
*/
static const struct geni_i2c_clk_fld geni_i2c_clk_map[] = {
{I2C_SPEED_STANDARD_RATE, 7, 10, 11, 26},
{I2C_SPEED_FAST_RATE, 2, 5, 12, 24},
{I2C_SPEED_FAST_PLUS_RATE, 1, 3, 9, 18},
};
static int geni_i2c_clk_map_idx(struct geni_i2c_priv *geni, unsigned int clk_freq)
{
const struct geni_i2c_clk_fld *itr = geni_i2c_clk_map;
int i;
for (i = 0; i < ARRAY_SIZE(geni_i2c_clk_map); i++, itr++) {
if (itr->clk_freq_out == clk_freq) {
geni->clk_fld = itr;
return 0;
}
}
return -EINVAL;
}
static void geni_i2c_setup_m_cmd(struct geni_i2c_priv *geni, u32 cmd, u32 params)
{
u32 m_cmd;
m_cmd = (cmd << M_OPCODE_SHFT) | (params & M_PARAMS_MSK);
writel(m_cmd, geni->base + SE_GENI_M_CMD0);
}
static void qcom_geni_i2c_conf(struct geni_i2c_priv *geni)
{
const struct geni_i2c_clk_fld *itr = geni->clk_fld;
u32 val;
writel(0, geni->base + SE_GENI_CLK_SEL);
val = (itr->clk_div << CLK_DIV_SHFT) | SER_CLK_EN;
writel(val, geni->base + GENI_SER_M_CLK_CFG);
val = itr->t_high_cnt << HIGH_COUNTER_SHFT;
val |= itr->t_low_cnt << LOW_COUNTER_SHFT;
val |= itr->t_cycle_cnt;
writel(val, geni->base + SE_I2C_SCL_COUNTERS);
writel(0xffffffff, geni->base + SE_GENI_M_IRQ_CLEAR);
}
static int geni_i2c_fifo_tx_fill(struct geni_i2c_priv *geni, struct i2c_msg *msg)
{
ulong start = get_timer(0);
ulong cur_xfer = 0;
int i;
while (get_timer(start) < I2C_TIMEOUT_MS) {
u32 status = readl(geni->base + SE_GENI_M_IRQ_STATUS);
if (status & (M_CMD_ABORT_EN |
M_CMD_OVERRUN_EN |
M_ILLEGAL_CMD_EN |
M_CMD_FAILURE_EN |
M_GP_IRQ_1_EN |
M_GP_IRQ_3_EN |
M_GP_IRQ_4_EN)) {
writel(status, geni->base + SE_GENI_M_IRQ_CLEAR);
writel(0, geni->base + SE_GENI_TX_WATERMARK_REG);
return -EREMOTEIO;
}
if ((status & M_TX_FIFO_WATERMARK_EN) == 0) {
udelay(1);
goto skip_fill;
}
for (i = 0; i < geni->tx_wm; i++) {
u32 temp, tx = 0;
unsigned int p = 0;
while (cur_xfer < msg->len && p < sizeof(tx)) {
temp = msg->buf[cur_xfer++];
tx |= temp << (p * 8);
p++;
}
writel(tx, geni->base + SE_GENI_TX_FIFOn);
if (cur_xfer == msg->len) {
writel(0, geni->base + SE_GENI_TX_WATERMARK_REG);
break;
}
}
skip_fill:
writel(status, geni->base + SE_GENI_M_IRQ_CLEAR);
if (status & M_CMD_DONE_EN)
return 0;
}
return -ETIMEDOUT;
}
static int geni_i2c_fifo_rx_drain(struct geni_i2c_priv *geni, struct i2c_msg *msg)
{
ulong start = get_timer(0);
ulong cur_xfer = 0;
int i;
while (get_timer(start) < I2C_TIMEOUT_MS) {
u32 status = readl(geni->base + SE_GENI_M_IRQ_STATUS);
u32 rxstatus = readl(geni->base + SE_GENI_RX_FIFO_STATUS);
u32 rxcnt = rxstatus & RX_FIFO_WC_MSK;
if (status & (M_CMD_ABORT_EN |
M_CMD_FAILURE_EN |
M_CMD_OVERRUN_EN |
M_ILLEGAL_CMD_EN |
M_GP_IRQ_1_EN |
M_GP_IRQ_3_EN |
M_GP_IRQ_4_EN)) {
writel(status, geni->base + SE_GENI_M_IRQ_CLEAR);
return -EREMOTEIO;
}
if ((status & (M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN)) == 0) {
udelay(1);
goto skip_drain;
}
for (i = 0; cur_xfer < msg->len && i < rxcnt; i++) {
u32 rx = readl(geni->base + SE_GENI_RX_FIFOn);
unsigned int p = 0;
while (cur_xfer < msg->len && p < sizeof(rx)) {
msg->buf[cur_xfer++] = rx & 0xff;
rx >>= 8;
p++;
}
}
skip_drain:
writel(status, geni->base + SE_GENI_M_IRQ_CLEAR);
if (status & M_CMD_DONE_EN)
return 0;
}
return -ETIMEDOUT;
}
static int geni_i2c_xfer_tx(struct geni_i2c_priv *geni, struct i2c_msg *msg, u32 params)
{
writel(msg->len, geni->base + SE_I2C_TX_TRANS_LEN);
geni_i2c_setup_m_cmd(geni, I2C_WRITE, params);
writel(1, geni->base + SE_GENI_TX_WATERMARK_REG);
return geni_i2c_fifo_tx_fill(geni, msg);
}
static int geni_i2c_xfer_rx(struct geni_i2c_priv *geni, struct i2c_msg *msg, u32 params)
{
writel(msg->len, geni->base + SE_I2C_RX_TRANS_LEN);
geni_i2c_setup_m_cmd(geni, I2C_READ, params);
return geni_i2c_fifo_rx_drain(geni, msg);
}
static int geni_i2c_xfer(struct udevice *bus, struct i2c_msg msgs[], int num)
{
struct geni_i2c_priv *geni = dev_get_priv(bus);
int i, ret = 0;
qcom_geni_i2c_conf(geni);
for (i = 0; i < num; i++) {
struct i2c_msg *msg = &msgs[i];
u32 m_param = i < (num - 1) ? STOP_STRETCH : 0;
m_param |= ((msg->addr << SLV_ADDR_SHFT) & SLV_ADDR_MSK);
if (msg->flags & I2C_M_RD)
ret = geni_i2c_xfer_rx(geni, msg, m_param);
else
ret = geni_i2c_xfer_tx(geni, msg, m_param);
if (ret)
break;
}
if (ret) {
if (ret == -ETIMEDOUT) {
u32 status;
writel(M_GENI_CMD_ABORT, geni->base + SE_GENI_M_CMD_CTRL_REG);
/* Wait until Abort has finished */
do {
status = readl(geni->base + SE_GENI_M_IRQ_STATUS);
} while ((status & M_CMD_ABORT_EN) == 0);
writel(status, geni->base + SE_GENI_M_IRQ_STATUS);
}
return ret;
}
return 0;
}
static int geni_i2c_enable_clocks(struct udevice *dev, struct geni_i2c_priv *geni)
{
int ret;
if (geni->is_master_hub) {
ret = clk_enable(&geni->core);
if (ret) {
dev_err(dev, "clk_enable core failed %d\n", ret);
return ret;
}
}
ret = clk_enable(&geni->se);
if (ret) {
dev_err(dev, "clk_enable se failed %d\n", ret);
return ret;
}
return 0;
}
static int geni_i2c_disable_clocks(struct udevice *dev, struct geni_i2c_priv *geni)
{
int ret;
if (geni->is_master_hub) {
ret = clk_disable(&geni->core);
if (ret) {
dev_err(dev, "clk_enable core failed %d\n", ret);
return ret;
}
}
ret = clk_disable(&geni->se);
if (ret) {
dev_err(dev, "clk_enable se failed %d\n", ret);
return ret;
}
return 0;
}
#define NUM_PACKING_VECTORS 4
#define PACKING_START_SHIFT 5
#define PACKING_DIR_SHIFT 4
#define PACKING_LEN_SHIFT 1
#define PACKING_STOP_BIT BIT(0)
#define PACKING_VECTOR_SHIFT 10
static void geni_i2c_config_packing(struct geni_i2c_priv *geni, int bpw,
int pack_words, bool msb_to_lsb,
bool tx_cfg, bool rx_cfg)
{
u32 cfg0, cfg1, cfg[NUM_PACKING_VECTORS] = {0};
int len;
int temp_bpw = bpw;
int idx_start = msb_to_lsb ? bpw - 1 : 0;
int idx = idx_start;
int idx_delta = msb_to_lsb ? -BITS_PER_BYTE : BITS_PER_BYTE;
int ceil_bpw = ALIGN(bpw, BITS_PER_BYTE);
int iter = (ceil_bpw * pack_words) / BITS_PER_BYTE;
int i;
if (iter <= 0 || iter > NUM_PACKING_VECTORS)
return;
for (i = 0; i < iter; i++) {
len = min_t(int, temp_bpw, BITS_PER_BYTE) - 1;
cfg[i] = idx << PACKING_START_SHIFT;
cfg[i] |= msb_to_lsb << PACKING_DIR_SHIFT;
cfg[i] |= len << PACKING_LEN_SHIFT;
if (temp_bpw <= BITS_PER_BYTE) {
idx = ((i + 1) * BITS_PER_BYTE) + idx_start;
temp_bpw = bpw;
} else {
idx = idx + idx_delta;
temp_bpw = temp_bpw - BITS_PER_BYTE;
}
}
cfg[iter - 1] |= PACKING_STOP_BIT;
cfg0 = cfg[0] | (cfg[1] << PACKING_VECTOR_SHIFT);
cfg1 = cfg[2] | (cfg[3] << PACKING_VECTOR_SHIFT);
if (tx_cfg) {
writel(cfg0, geni->base + SE_GENI_TX_PACKING_CFG0);
writel(cfg1, geni->base + SE_GENI_TX_PACKING_CFG1);
}
if (rx_cfg) {
writel(cfg0, geni->base + SE_GENI_RX_PACKING_CFG0);
writel(cfg1, geni->base + SE_GENI_RX_PACKING_CFG1);
}
/*
* Number of protocol words in each FIFO entry
* 0 - 4x8, four words in each entry, max word size of 8 bits
* 1 - 2x16, two words in each entry, max word size of 16 bits
* 2 - 1x32, one word in each entry, max word size of 32 bits
* 3 - undefined
*/
if (pack_words || bpw == 32)
writel(bpw / 16, geni->base + SE_GENI_BYTE_GRAN);
}
static void geni_i2c_init(struct geni_i2c_priv *geni, unsigned int tx_depth)
{
u32 val;
writel(0, geni->base + SE_GSI_EVENT_EN);
writel(0xffffffff, geni->base + SE_GENI_M_IRQ_CLEAR);
writel(0xffffffff, geni->base + SE_GENI_S_IRQ_CLEAR);
writel(0xffffffff, geni->base + SE_IRQ_EN);
val = readl(geni->base + GENI_CGC_CTRL);
val |= DEFAULT_CGC_EN;
writel(val, geni->base + GENI_CGC_CTRL);
writel(DEFAULT_IO_OUTPUT_CTRL_MSK, geni->base + GENI_OUTPUT_CTRL);
writel(FORCE_DEFAULT, geni->base + GENI_FORCE_DEFAULT_REG);
val = readl(geni->base + SE_IRQ_EN);
val |= GENI_M_IRQ_EN | GENI_S_IRQ_EN;
writel(val, geni->base + SE_IRQ_EN);
val = readl(geni->base + SE_GENI_DMA_MODE_EN);
val &= ~GENI_DMA_MODE_EN;
writel(val, geni->base + SE_GENI_DMA_MODE_EN);
writel(0, geni->base + SE_GSI_EVENT_EN);
writel(tx_depth - 1, geni->base + SE_GENI_RX_WATERMARK_REG);
writel(tx_depth, geni->base + SE_GENI_RX_RFR_WATERMARK_REG);
val = readl(geni->base + SE_GENI_M_IRQ_EN);
val |= M_COMMON_GENI_M_IRQ_EN;
val |= M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN;
val |= M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN;
writel(val, geni->base + SE_GENI_M_IRQ_EN);
val = readl(geni->base + SE_GENI_S_IRQ_EN);
val |= S_COMMON_GENI_S_IRQ_EN;
writel(val, geni->base + SE_GENI_S_IRQ_EN);
}
static u32 geni_i2c_get_tx_fifo_depth(struct geni_i2c_priv *geni)
{
u32 val, hw_version, hw_major, hw_minor, tx_fifo_depth_mask;
hw_version = readl(geni->wrapper + QUP_HW_VER_REG);
hw_major = GENI_SE_VERSION_MAJOR(hw_version);
hw_minor = GENI_SE_VERSION_MINOR(hw_version);
if ((hw_major == 3 && hw_minor >= 10) || hw_major > 3)
tx_fifo_depth_mask = TX_FIFO_DEPTH_MSK_256_BYTES;
else
tx_fifo_depth_mask = TX_FIFO_DEPTH_MSK;
val = readl(geni->base + SE_HW_PARAM_0);
return (val & tx_fifo_depth_mask) >> TX_FIFO_DEPTH_SHFT;
}
static int geni_i2c_probe(struct udevice *dev)
{
ofnode parent_node = ofnode_get_parent(dev_ofnode(dev));
struct geni_i2c_priv *geni = dev_get_priv(dev);
u32 proto, tx_depth, fifo_disable;
int ret;
geni->is_master_hub = dev_get_driver_data(dev) & GENI_I2C_IS_MASTER_HUB;
geni->wrapper = ofnode_get_addr(parent_node);
if (geni->wrapper == FDT_ADDR_T_NONE)
return -EINVAL;
geni->base = (phys_addr_t)dev_read_addr_ptr(dev);
if (!geni->base)
return -EINVAL;
if (geni->is_master_hub) {
ret = clk_get_by_name(dev, "core", &geni->core);
if (ret) {
dev_err(dev, "clk_get_by_name(core) failed: %d\n", ret);
return ret;
}
}
ret = clk_get_by_name(dev, "se", &geni->se);
if (ret) {
dev_err(dev, "clk_get_by_name(se) failed: %d\n", ret);
return ret;
}
geni_i2c_enable_clocks(dev, geni);
proto = readl(geni->base + GENI_FW_REVISION_RO);
proto &= FW_REV_PROTOCOL_MSK;
proto >>= FW_REV_PROTOCOL_SHFT;
if (proto != GENI_SE_I2C) {
dev_err(dev, "Invalid proto %d\n", proto);
geni_i2c_disable_clocks(dev, geni);
return -ENXIO;
}
fifo_disable = readl(geni->base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE;
if (fifo_disable) {
geni_i2c_disable_clocks(dev, geni);
dev_err(dev, "FIFO mode disabled, DMA mode unsupported\n");
return -ENXIO;
}
if (!geni->is_master_hub) {
tx_depth = geni_i2c_get_tx_fifo_depth(geni);
if (!tx_depth) {
geni_i2c_disable_clocks(dev, geni);
dev_err(dev, "Invalid TX FIFO depth\n");
return -ENXIO;
}
} else {
tx_depth = 16;
}
geni->tx_wm = tx_depth - 1;
geni_i2c_init(geni, tx_depth);
geni_i2c_config_packing(geni, BITS_PER_BYTE,
PACKING_BYTES_PW, true, true, true);
/* Setup for standard rate */
return geni_i2c_clk_map_idx(geni, I2C_SPEED_STANDARD_RATE);
}
static int geni_i2c_set_bus_speed(struct udevice *dev, unsigned int clk_freq)
{
struct geni_i2c_priv *geni = dev_get_priv(dev);
return geni_i2c_clk_map_idx(geni, clk_freq);
}
static const struct dm_i2c_ops geni_i2c_ops = {
.xfer = geni_i2c_xfer,
.set_bus_speed = geni_i2c_set_bus_speed,
};
static const struct udevice_id geni_i2c_ids[] = {
{ .compatible = "qcom,geni-i2c" },
{ .compatible = "qcom,geni-i2c-master-hub", .data = GENI_I2C_IS_MASTER_HUB},
{}
};
U_BOOT_DRIVER(i2c_geni) = {
.name = "i2c_geni",
.id = UCLASS_I2C,
.of_match = geni_i2c_ids,
.probe = geni_i2c_probe,
.priv_auto = sizeof(struct geni_i2c_priv),
.ops = &geni_i2c_ops,
};
static const struct udevice_id geni_i2c_master_hub_ids[] = {
{ .compatible = "qcom,geni-se-i2c-master-hub" },
{ }
};
U_BOOT_DRIVER(geni_i2c_master_hub) = {
.name = "geni-se-master-hub",
.id = UCLASS_NOP,
.of_match = geni_i2c_master_hub_ids,
.bind = dm_scan_fdt_dev,
.flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF,
};

View File

@@ -381,6 +381,7 @@ static struct iommu_ops qcom_smmu_ops = {
static const struct udevice_id qcom_smmu500_ids[] = {
{ .compatible = "qcom,sdm845-smmu-500" },
{ .compatible = "qcom,smmu-500", },
{ /* sentinel */ }
};

View File

@@ -33,9 +33,6 @@
#define SDCC_MCI_STATUS2_MCI_ACT 0x1
#define SDCC_MCI_HC_MODE 0x78
/* Non standard (?) SDHCI register */
#define SDHCI_VENDOR_SPEC_CAPABILITIES0 0x11c
struct msm_sdhc_plat {
struct mmc_config cfg;
struct mmc mmc;
@@ -49,6 +46,8 @@ struct msm_sdhc {
struct msm_sdhc_variant_info {
bool mci_removed;
u32 core_vendor_spec_capabilities0;
};
DECLARE_GLOBAL_DATA_PTR;
@@ -63,7 +62,7 @@ static int msm_sdc_clk_init(struct udevice *dev)
ret = ofnode_read_u32(node, "clock-frequency", (uint *)(&clk_rate));
if (ret)
clk_rate = 400000;
clk_rate = 201500000;
ret = clk_get_bulk(dev, &prv->clks);
if (ret) {
@@ -174,6 +173,8 @@ static int msm_sdc_probe(struct udevice *dev)
core_minor = core_version & SDCC_VERSION_MINOR_MASK;
log_debug("SDCC version %d.%d\n", core_major, core_minor);
/*
* Support for some capabilities is not advertised by newer
* controller versions and must be explicitly enabled.
@@ -181,7 +182,7 @@ static int msm_sdc_probe(struct udevice *dev)
if (core_major >= 1 && core_minor != 0x11 && core_minor != 0x12) {
caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
caps |= SDHCI_CAN_VDD_300 | SDHCI_CAN_DO_8BIT;
writel(caps, host->ioaddr + SDHCI_VENDOR_SPEC_CAPABILITIES0);
writel(caps, host->ioaddr + var_info->core_vendor_spec_capabilities0);
}
ret = mmc_of_parse(dev, &plat->cfg);
@@ -207,7 +208,7 @@ static int msm_sdc_remove(struct udevice *dev)
var_info = (void *)dev_get_driver_data(dev);
/* Disable host-controller mode */
if (!var_info->mci_removed)
if (!var_info->mci_removed && priv->base)
writel(0, priv->base + SDCC_MCI_HC_MODE);
clk_release_bulk(&priv->clks);
@@ -217,21 +218,31 @@ static int msm_sdc_remove(struct udevice *dev)
static int msm_of_to_plat(struct udevice *dev)
{
struct udevice *parent = dev->parent;
struct msm_sdhc *priv = dev_get_priv(dev);
const struct msm_sdhc_variant_info *var_info;
struct sdhci_host *host = &priv->host;
int node = dev_of_offset(dev);
int ret;
var_info = (void*)dev_get_driver_data(dev);
host->name = strdup(dev->name);
host->ioaddr = dev_read_addr_ptr(dev);
host->bus_width = fdtdec_get_int(gd->fdt_blob, node, "bus-width", 4);
host->index = fdtdec_get_uint(gd->fdt_blob, node, "index", 0);
priv->base = (void *)fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
dev_of_offset(parent), node, "reg", 1, NULL, false);
if (priv->base == (void *)FDT_ADDR_T_NONE ||
host->ioaddr == (void *)FDT_ADDR_T_NONE)
ret = dev_read_u32(dev, "bus-width", &host->bus_width);
if (ret)
host->bus_width = 4;
ret = dev_read_u32(dev, "index", &host->index);
if (ret)
host->index = 0;
priv->base = dev_read_addr_index_ptr(dev, 1);
if (!host->ioaddr)
return -EINVAL;
if (!var_info->mci_removed && !priv->base) {
printf("msm_sdhci: MCI base address not found\n");
return -EINVAL;
}
return 0;
}
@@ -244,10 +255,14 @@ static int msm_sdc_bind(struct udevice *dev)
static const struct msm_sdhc_variant_info msm_sdhc_mci_var = {
.mci_removed = false,
.core_vendor_spec_capabilities0 = 0x11c,
};
static const struct msm_sdhc_variant_info msm_sdhc_v5_var = {
.mci_removed = true,
.core_vendor_spec_capabilities0 = 0x21c,
};
static const struct udevice_id msm_mmc_ids[] = {

View File

@@ -27,6 +27,14 @@ config PHY_QCOM_USB_SNPS_FEMTO_V2
High-Speed PHY driver. This driver supports the Hi-Speed PHY which
is usually paired with Synopsys DWC3 USB IPs on MSM SOCs.
config PHY_QCOM_SNPS_EUSB2
tristate "Qualcomm Synopsys eUSB2 High-Speed PHY"
depends on PHY && ARCH_SNAPDRAGON
help
Enable this to support the Qualcomm Synopsys DesignWare eUSB2
High-Speed PHY driver. This driver supports the Hi-Speed PHY which
is usually paired with Synopsys DWC3 USB IPs on MSM SOCs.
config PHY_QCOM_USB_HS_28NM
tristate "Qualcomm 28nm High-Speed PHY"
depends on PHY && ARCH_SNAPDRAGON

View File

@@ -2,5 +2,6 @@ obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o
obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
obj-$(CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2) += phy-qcom-snps-femto-v2.o
obj-$(CONFIG_PHY_QCOM_SNPS_EUSB2) += phy-qcom-snps-eusb2.o
obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o
obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o

View File

@@ -0,0 +1,366 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2023-2024, Linaro Limited
*
* Based on the Linux phy-qcom-snps-eusb2.c driver
*/
#include <clk.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
#include <generic-phy.h>
#include <malloc.h>
#include <reset.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <linux/bitfield.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#define USB_PHY_UTMI_CTRL0 (0x3c)
#define SLEEPM BIT(0)
#define OPMODE_MASK GENMASK(4, 3)
#define OPMODE_NONDRIVING BIT(3)
#define USB_PHY_UTMI_CTRL5 (0x50)
#define POR BIT(1)
#define USB_PHY_HS_PHY_CTRL_COMMON0 (0x54)
#define PHY_ENABLE BIT(0)
#define SIDDQ_SEL BIT(1)
#define SIDDQ BIT(2)
#define RETENABLEN BIT(3)
#define FSEL_MASK GENMASK(6, 4)
#define FSEL_19_2_MHZ_VAL (0x0)
#define FSEL_38_4_MHZ_VAL (0x4)
#define USB_PHY_CFG_CTRL_1 (0x58)
#define PHY_CFG_PLL_CPBIAS_CNTRL_MASK GENMASK(7, 1)
#define USB_PHY_CFG_CTRL_2 (0x5c)
#define PHY_CFG_PLL_FB_DIV_7_0_MASK GENMASK(7, 0)
#define DIV_7_0_19_2_MHZ_VAL (0x90)
#define DIV_7_0_38_4_MHZ_VAL (0xc8)
#define USB_PHY_CFG_CTRL_3 (0x60)
#define PHY_CFG_PLL_FB_DIV_11_8_MASK GENMASK(3, 0)
#define DIV_11_8_19_2_MHZ_VAL (0x1)
#define DIV_11_8_38_4_MHZ_VAL (0x0)
#define PHY_CFG_PLL_REF_DIV GENMASK(7, 4)
#define PLL_REF_DIV_VAL (0x0)
#define USB_PHY_HS_PHY_CTRL2 (0x64)
#define VBUSVLDEXT0 BIT(0)
#define USB2_SUSPEND_N BIT(2)
#define USB2_SUSPEND_N_SEL BIT(3)
#define VBUS_DET_EXT_SEL BIT(4)
#define USB_PHY_CFG_CTRL_4 (0x68)
#define PHY_CFG_PLL_GMP_CNTRL_MASK GENMASK(1, 0)
#define PHY_CFG_PLL_INT_CNTRL_MASK GENMASK(7, 2)
#define USB_PHY_CFG_CTRL_5 (0x6c)
#define PHY_CFG_PLL_PROP_CNTRL_MASK GENMASK(4, 0)
#define PHY_CFG_PLL_VREF_TUNE_MASK GENMASK(7, 6)
#define USB_PHY_CFG_CTRL_6 (0x70)
#define PHY_CFG_PLL_VCO_CNTRL_MASK GENMASK(2, 0)
#define USB_PHY_CFG_CTRL_7 (0x74)
#define USB_PHY_CFG_CTRL_8 (0x78)
#define PHY_CFG_TX_FSLS_VREF_TUNE_MASK GENMASK(1, 0)
#define PHY_CFG_TX_FSLS_VREG_BYPASS BIT(2)
#define PHY_CFG_TX_HS_VREF_TUNE_MASK GENMASK(5, 3)
#define PHY_CFG_TX_HS_XV_TUNE_MASK GENMASK(7, 6)
#define USB_PHY_CFG_CTRL_9 (0x7c)
#define PHY_CFG_TX_PREEMP_TUNE_MASK GENMASK(2, 0)
#define PHY_CFG_TX_RES_TUNE_MASK GENMASK(4, 3)
#define PHY_CFG_TX_RISE_TUNE_MASK GENMASK(6, 5)
#define PHY_CFG_RCAL_BYPASS BIT(7)
#define USB_PHY_CFG_CTRL_10 (0x80)
#define USB_PHY_CFG0 (0x94)
#define DATAPATH_CTRL_OVERRIDE_EN BIT(0)
#define CMN_CTRL_OVERRIDE_EN BIT(1)
#define UTMI_PHY_CMN_CTRL0 (0x98)
#define TESTBURNIN BIT(6)
#define USB_PHY_FSEL_SEL (0xb8)
#define FSEL_SEL BIT(0)
#define USB_PHY_APB_ACCESS_CMD (0x130)
#define RW_ACCESS BIT(0)
#define APB_START_CMD BIT(1)
#define APB_LOGIC_RESET BIT(2)
#define USB_PHY_APB_ACCESS_STATUS (0x134)
#define ACCESS_DONE BIT(0)
#define TIMED_OUT BIT(1)
#define ACCESS_ERROR BIT(2)
#define ACCESS_IN_PROGRESS BIT(3)
#define USB_PHY_APB_ADDRESS (0x138)
#define APB_REG_ADDR_MASK GENMASK(7, 0)
#define USB_PHY_APB_WRDATA_LSB (0x13c)
#define APB_REG_WRDATA_7_0_MASK GENMASK(3, 0)
#define USB_PHY_APB_WRDATA_MSB (0x140)
#define APB_REG_WRDATA_15_8_MASK GENMASK(7, 4)
#define USB_PHY_APB_RDDATA_LSB (0x144)
#define APB_REG_RDDATA_7_0_MASK GENMASK(3, 0)
#define USB_PHY_APB_RDDATA_MSB (0x148)
#define APB_REG_RDDATA_15_8_MASK GENMASK(7, 4)
struct qcom_snps_eusb2_phy_priv {
void __iomem *base;
struct clk *ref_clk;
struct reset_ctl_bulk resets;
};
static void qcom_snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset,
u32 mask, u32 val)
{
u32 reg;
reg = readl_relaxed(base + offset);
reg &= ~mask;
reg |= val & mask;
writel_relaxed(reg, base + offset);
/* Ensure above write is completed */
readl_relaxed(base + offset);
}
static void qcom_eusb2_default_parameters(struct qcom_snps_eusb2_phy_priv *qcom_snps_eusb2)
{
/* default parameters: tx pre-emphasis */
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_9,
PHY_CFG_TX_PREEMP_TUNE_MASK,
FIELD_PREP(PHY_CFG_TX_PREEMP_TUNE_MASK, 0));
/* tx rise/fall time */
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_9,
PHY_CFG_TX_RISE_TUNE_MASK,
FIELD_PREP(PHY_CFG_TX_RISE_TUNE_MASK, 0x2));
/* source impedance adjustment */
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_9,
PHY_CFG_TX_RES_TUNE_MASK,
FIELD_PREP(PHY_CFG_TX_RES_TUNE_MASK, 0x1));
/* dc voltage level adjustement */
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_8,
PHY_CFG_TX_HS_VREF_TUNE_MASK,
FIELD_PREP(PHY_CFG_TX_HS_VREF_TUNE_MASK, 0x3));
/* transmitter HS crossover adjustement */
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_8,
PHY_CFG_TX_HS_XV_TUNE_MASK,
FIELD_PREP(PHY_CFG_TX_HS_XV_TUNE_MASK, 0x0));
}
static int qcom_eusb2_ref_clk_init(struct qcom_snps_eusb2_phy_priv *qcom_snps_eusb2)
{
unsigned long ref_clk_freq = clk_get_rate(qcom_snps_eusb2->ref_clk);
switch (ref_clk_freq) {
case 19200000:
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_HS_PHY_CTRL_COMMON0,
FSEL_MASK,
FIELD_PREP(FSEL_MASK, FSEL_19_2_MHZ_VAL));
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_2,
PHY_CFG_PLL_FB_DIV_7_0_MASK,
DIV_7_0_19_2_MHZ_VAL);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_3,
PHY_CFG_PLL_FB_DIV_11_8_MASK,
DIV_11_8_19_2_MHZ_VAL);
break;
case 38400000:
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_HS_PHY_CTRL_COMMON0,
FSEL_MASK,
FIELD_PREP(FSEL_MASK, FSEL_38_4_MHZ_VAL));
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_2,
PHY_CFG_PLL_FB_DIV_7_0_MASK,
DIV_7_0_38_4_MHZ_VAL);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_3,
PHY_CFG_PLL_FB_DIV_11_8_MASK,
DIV_11_8_38_4_MHZ_VAL);
break;
default:
printf("%s: unsupported ref_clk_freq:%lu\n", __func__, ref_clk_freq);
return -EINVAL;
}
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_3,
PHY_CFG_PLL_REF_DIV, PLL_REF_DIV_VAL);
return 0;
}
static int qcom_snps_eusb2_usb_init(struct phy *phy)
{
struct qcom_snps_eusb2_phy_priv *qcom_snps_eusb2 = dev_get_priv(phy->dev);
int ret;
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG0,
CMN_CTRL_OVERRIDE_EN, CMN_CTRL_OVERRIDE_EN);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_UTMI_CTRL5, POR, POR);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_HS_PHY_CTRL_COMMON0,
PHY_ENABLE | RETENABLEN, PHY_ENABLE | RETENABLEN);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_APB_ACCESS_CMD,
APB_LOGIC_RESET, APB_LOGIC_RESET);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, UTMI_PHY_CMN_CTRL0, TESTBURNIN, 0);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_FSEL_SEL,
FSEL_SEL, FSEL_SEL);
/* update ref_clk related registers */
ret = qcom_eusb2_ref_clk_init(qcom_snps_eusb2);
if (ret)
return ret;
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_1,
PHY_CFG_PLL_CPBIAS_CNTRL_MASK,
FIELD_PREP(PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 0x1));
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_4,
PHY_CFG_PLL_INT_CNTRL_MASK,
FIELD_PREP(PHY_CFG_PLL_INT_CNTRL_MASK, 0x8));
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_4,
PHY_CFG_PLL_GMP_CNTRL_MASK,
FIELD_PREP(PHY_CFG_PLL_GMP_CNTRL_MASK, 0x1));
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_5,
PHY_CFG_PLL_PROP_CNTRL_MASK,
FIELD_PREP(PHY_CFG_PLL_PROP_CNTRL_MASK, 0x10));
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_6,
PHY_CFG_PLL_VCO_CNTRL_MASK,
FIELD_PREP(PHY_CFG_PLL_VCO_CNTRL_MASK, 0x0));
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_CFG_CTRL_5,
PHY_CFG_PLL_VREF_TUNE_MASK,
FIELD_PREP(PHY_CFG_PLL_VREF_TUNE_MASK, 0x1));
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_HS_PHY_CTRL2,
VBUS_DET_EXT_SEL, VBUS_DET_EXT_SEL);
/* set default parameters */
qcom_eusb2_default_parameters(qcom_snps_eusb2);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_HS_PHY_CTRL2,
USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
USB2_SUSPEND_N_SEL | USB2_SUSPEND_N);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_HS_PHY_CTRL_COMMON0,
SIDDQ_SEL, SIDDQ_SEL);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_HS_PHY_CTRL_COMMON0,
SIDDQ, 0);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_UTMI_CTRL5, POR, 0);
qcom_snps_eusb2_hsphy_write_mask(qcom_snps_eusb2->base, USB_PHY_HS_PHY_CTRL2,
USB2_SUSPEND_N_SEL, 0);
return 0;
}
static int qcom_snps_eusb2_phy_power_on(struct phy *phy)
{
struct qcom_snps_eusb2_phy_priv *qcom_snps_eusb2 = dev_get_priv(phy->dev);
int ret;
/* TODO Repeater */
clk_prepare_enable(qcom_snps_eusb2->ref_clk);
ret = reset_deassert_bulk(&qcom_snps_eusb2->resets);
if (ret)
return ret;
ret = qcom_snps_eusb2_usb_init(phy);
if (ret)
return ret;
return 0;
}
static int qcom_snps_eusb2_phy_power_off(struct phy *phy)
{
struct qcom_snps_eusb2_phy_priv *qcom_snps_eusb2 = dev_get_priv(phy->dev);
reset_assert_bulk(&qcom_snps_eusb2->resets);
clk_disable_unprepare(qcom_snps_eusb2->ref_clk);
return 0;
}
static int qcom_snps_eusb2_phy_probe(struct udevice *dev)
{
struct qcom_snps_eusb2_phy_priv *qcom_snps_eusb2 = dev_get_priv(dev);
int ret;
qcom_snps_eusb2->base = (void __iomem *)dev_read_addr(dev);
if (IS_ERR(qcom_snps_eusb2->base))
return PTR_ERR(qcom_snps_eusb2->base);
qcom_snps_eusb2->ref_clk = devm_clk_get(dev, "ref");
if (IS_ERR(qcom_snps_eusb2->ref_clk)) {
printf("%s: failed to get ref clk %d\n", __func__, ret);
return PTR_ERR(qcom_snps_eusb2->ref_clk);
}
ret = reset_get_bulk(dev, &qcom_snps_eusb2->resets);
if (ret < 0) {
printf("failed to get resets, ret = %d\n", ret);
return ret;
}
return 0;
}
static struct phy_ops qcom_snps_eusb2_phy_ops = {
.power_on = qcom_snps_eusb2_phy_power_on,
.power_off = qcom_snps_eusb2_phy_power_off,
};
static const struct udevice_id qcom_snps_eusb2_phy_ids[] = {
{
.compatible = "qcom,sm8550-snps-eusb2-phy",
},
{}
};
U_BOOT_DRIVER(qcom_usb_qcom_snps_eusb2) = {
.name = "qcom-snps-eusb2-hsphy",
.id = UCLASS_PHY,
.of_match = qcom_snps_eusb2_phy_ids,
.ops = &qcom_snps_eusb2_phy_ops,
.probe = qcom_snps_eusb2_phy_probe,
.priv_auto = sizeof(struct qcom_snps_eusb2_phy_priv),
};

View File

@@ -6,8 +6,6 @@
* Based on Linux driver
*/
#include <clk.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
@@ -17,7 +15,6 @@
#include <asm/io.h>
#include <linux/bitops.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
@@ -62,7 +59,6 @@
struct qcom_snps_hsphy {
void __iomem *base;
struct clk_bulk clks;
struct reset_ctl_bulk resets;
};
@@ -143,8 +139,6 @@ static int qcom_snps_hsphy_power_on(struct phy *phy)
struct qcom_snps_hsphy *priv = dev_get_priv(phy->dev);
int ret;
clk_enable_bulk(&priv->clks);
ret = reset_deassert_bulk(&priv->resets);
if (ret)
return ret;
@@ -161,7 +155,6 @@ static int qcom_snps_hsphy_power_off(struct phy *phy)
struct qcom_snps_hsphy *priv = dev_get_priv(phy->dev);
reset_assert_bulk(&priv->resets);
clk_disable_bulk(&priv->clks);
return 0;
}
@@ -175,19 +168,12 @@ static int qcom_snps_hsphy_phy_probe(struct udevice *dev)
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
ret = clk_get_bulk(dev, &priv->clks);
if (ret < 0 && ret != -ENOENT) {
printf("%s: Failed to get clocks %d\n", __func__, ret);
return ret;
}
ret = reset_get_bulk(dev, &priv->resets);
if (ret < 0) {
printf("failed to get resets, ret = %d\n", ret);
return ret;
}
clk_enable_bulk(&priv->clks);
reset_deassert_bulk(&priv->resets);
return 0;

View File

@@ -1,4 +1,4 @@
if ARCH_SNAPDRAGON
if ARCH_SNAPDRAGON || ARCH_IPQ40XX
config PINCTRL_QCOM
depends on PINCTRL_GENERIC
@@ -27,6 +27,13 @@ config PINCTRL_QCOM_IPQ4019
Say Y here to enable support for pinctrl on the IPQ4019 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_QCM2290
bool "Qualcomm QCM2290 GCC"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon QCM2290 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_QCS404
bool "Qualcomm QCS404 GCC"
select PINCTRL_QCOM
@@ -41,6 +48,33 @@ config PINCTRL_QCOM_SDM845
Say Y here to enable support for pinctrl on the Snapdragon 845 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_SM6115
bool "Qualcomm SM6115 GCC"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM6115 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_SM8250
bool "Qualcomm SM8250 GCC"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8250 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_SM8550
bool "Qualcomm SM8550 GCC"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8550 SoC,
as well as the associated GPIO driver.
config PINCTRL_QCOM_SM8650
bool "Qualcomm SM8650 GCC"
select PINCTRL_QCOM
help
Say Y here to enable support for pinctrl on the Snapdragon SM8650 SoC,
endmenu
endif

View File

@@ -6,5 +6,10 @@ obj-$(CONFIG_PINCTRL_QCOM) += pinctrl-qcom.o
obj-$(CONFIG_PINCTRL_QCOM_APQ8016) += pinctrl-apq8016.o
obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.o
obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o
obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o
obj-$(CONFIG_PINCTRL_QCOM_QCS404) += pinctrl-qcs404.o
obj-$(CONFIG_PINCTRL_QCOM_SDM845) += pinctrl-sdm845.o
obj-$(CONFIG_PINCTRL_QCOM_SM6115) += pinctrl-sm6115.o
obj-$(CONFIG_PINCTRL_QCOM_SM8250) += pinctrl-sm8250.o
obj-$(CONFIG_PINCTRL_QCOM_SM8550) += pinctrl-sm8550.o
obj-$(CONFIG_PINCTRL_QCOM_SM8650) += pinctrl-sm8650.o

View File

@@ -29,6 +29,8 @@ static const char * const msm_pinctrl_pins[] = {
};
static const struct pinctrl_function msm_pinctrl_functions[] = {
{"gpio", 0},
{"blsp_uart1", 2},
{"blsp_uart2", 2},
};

View File

@@ -14,19 +14,291 @@
#define MAX_PIN_NAME_LEN 32
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
static const struct pinctrl_function msm_pinctrl_functions[] = {
{"gpio", 0},
{"blsp_uart0_0", 1}, /* Only for GPIO:16,17 */
{"blsp_uart0_1", 2}, /* Only for GPIO:60,61 */
{"blsp_uart1", 1},
{"blsp_spi0_0", 1}, /* Only for GPIO:12,13,14,15 */
{"blsp_spi0_1", 2}, /* Only for GPIO:54,55,56,57 */
{"blsp_spi1", 2},
{"mdio_0", 1}, /* Only for GPIO6 */
{"mdio_1", 2}, /* Only for GPIO53 */
{"mdc_0", 1}, /* Only for GPIO7 */
{"mdc_1", 2}, /* Only for GPIO52 */
enum ipq4019_functions {
qca_mux_gpio,
qca_mux_aud_pin,
qca_mux_audio_pwm,
qca_mux_blsp_i2c0,
qca_mux_blsp_i2c1,
qca_mux_blsp_spi0,
qca_mux_blsp_spi1,
qca_mux_blsp_uart0,
qca_mux_blsp_uart1,
qca_mux_chip_rst,
qca_mux_i2s_rx,
qca_mux_i2s_spdif_in,
qca_mux_i2s_spdif_out,
qca_mux_i2s_td,
qca_mux_i2s_tx,
qca_mux_jtag,
qca_mux_led0,
qca_mux_led1,
qca_mux_led2,
qca_mux_led3,
qca_mux_led4,
qca_mux_led5,
qca_mux_led6,
qca_mux_led7,
qca_mux_led8,
qca_mux_led9,
qca_mux_led10,
qca_mux_led11,
qca_mux_mdc,
qca_mux_mdio,
qca_mux_pcie,
qca_mux_pmu,
qca_mux_prng_rosc,
qca_mux_qpic,
qca_mux_rgmii,
qca_mux_rmii,
qca_mux_sdio,
qca_mux_smart0,
qca_mux_smart1,
qca_mux_smart2,
qca_mux_smart3,
qca_mux_tm,
qca_mux_wifi0,
qca_mux_wifi1,
qca_mux_NA,
};
#define QCA_PIN_FUNCTION(fname) \
[qca_mux_##fname] = {#fname, qca_mux_##fname}
static const struct pinctrl_function msm_pinctrl_functions[] = {
QCA_PIN_FUNCTION(aud_pin),
QCA_PIN_FUNCTION(audio_pwm),
QCA_PIN_FUNCTION(blsp_i2c0),
QCA_PIN_FUNCTION(blsp_i2c1),
QCA_PIN_FUNCTION(blsp_spi0),
QCA_PIN_FUNCTION(blsp_spi1),
QCA_PIN_FUNCTION(blsp_uart0),
QCA_PIN_FUNCTION(blsp_uart1),
QCA_PIN_FUNCTION(chip_rst),
QCA_PIN_FUNCTION(gpio),
QCA_PIN_FUNCTION(i2s_rx),
QCA_PIN_FUNCTION(i2s_spdif_in),
QCA_PIN_FUNCTION(i2s_spdif_out),
QCA_PIN_FUNCTION(i2s_td),
QCA_PIN_FUNCTION(i2s_tx),
QCA_PIN_FUNCTION(jtag),
QCA_PIN_FUNCTION(led0),
QCA_PIN_FUNCTION(led1),
QCA_PIN_FUNCTION(led2),
QCA_PIN_FUNCTION(led3),
QCA_PIN_FUNCTION(led4),
QCA_PIN_FUNCTION(led5),
QCA_PIN_FUNCTION(led6),
QCA_PIN_FUNCTION(led7),
QCA_PIN_FUNCTION(led8),
QCA_PIN_FUNCTION(led9),
QCA_PIN_FUNCTION(led10),
QCA_PIN_FUNCTION(led11),
QCA_PIN_FUNCTION(mdc),
QCA_PIN_FUNCTION(mdio),
QCA_PIN_FUNCTION(pcie),
QCA_PIN_FUNCTION(pmu),
QCA_PIN_FUNCTION(prng_rosc),
QCA_PIN_FUNCTION(qpic),
QCA_PIN_FUNCTION(rgmii),
QCA_PIN_FUNCTION(rmii),
QCA_PIN_FUNCTION(sdio),
QCA_PIN_FUNCTION(smart0),
QCA_PIN_FUNCTION(smart1),
QCA_PIN_FUNCTION(smart2),
QCA_PIN_FUNCTION(smart3),
QCA_PIN_FUNCTION(tm),
QCA_PIN_FUNCTION(wifi0),
QCA_PIN_FUNCTION(wifi1),
};
typedef unsigned int msm_pin_function[15];
#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14) \
[id] = { qca_mux_gpio, /* gpio mode */ \
qca_mux_##f1, \
qca_mux_##f2, \
qca_mux_##f3, \
qca_mux_##f4, \
qca_mux_##f5, \
qca_mux_##f6, \
qca_mux_##f7, \
qca_mux_##f8, \
qca_mux_##f9, \
qca_mux_##f10, \
qca_mux_##f11, \
qca_mux_##f12, \
qca_mux_##f13, \
qca_mux_##f14 \
}
static const msm_pin_function ipq4019_pin_functions[] = {
PINGROUP(0, jtag, smart0, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(1, jtag, smart0, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(2, jtag, smart0, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(3, jtag, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(4, jtag, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(5, jtag, smart0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA),
PINGROUP(6, mdio, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(7, mdc, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(8, blsp_uart1, NA, NA, smart1, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(9, blsp_uart1, NA, NA, smart1, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(10, blsp_uart1, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(11, blsp_uart1, NA, NA, blsp_i2c0, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(12, blsp_spi0, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(13, blsp_spi0, blsp_i2c1, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(14, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA),
PINGROUP(15, blsp_spi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA),
PINGROUP(16, blsp_uart0, led0, smart1, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(17, blsp_uart0, led1, smart1, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(18, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(19, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(20, blsp_i2c0, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(21, blsp_i2c0, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(22, rgmii, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA),
PINGROUP(23, sdio, rgmii, i2s_rx, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(24, sdio, rgmii, i2s_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(25, sdio, rgmii, i2s_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(26, sdio, rgmii, i2s_tx, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(27, sdio, rgmii, i2s_td, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(28, sdio, rgmii, i2s_td, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(29, sdio, rgmii, i2s_td, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(30, sdio, rgmii, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(31, sdio, rgmii, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(32, sdio, rgmii, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(33, rgmii, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(34, blsp_i2c1, i2s_spdif_in, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA),
PINGROUP(35, blsp_i2c1, i2s_spdif_out, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA),
PINGROUP(36, rmii, led2, led0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA),
PINGROUP(37, rmii, wifi0, wifi1, led1, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(38, rmii, led2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA),
PINGROUP(39, rmii, pcie, led3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA),
PINGROUP(40, rmii, wifi0, wifi1, smart2, led4, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(41, rmii, wifi0, wifi1, smart2, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(42, rmii, wifi0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA),
PINGROUP(43, rmii, wifi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA),
PINGROUP(44, rmii, blsp_spi1, smart0, led5, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(45, rmii, blsp_spi1, blsp_spi0, smart0, led6, NA, NA, NA, NA,
NA, NA, NA, NA, NA),
PINGROUP(46, rmii, blsp_spi1, smart0, led7, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(47, rmii, blsp_spi1, smart0, led8, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(48, rmii, aud_pin, smart2, led9, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(49, rmii, aud_pin, smart2, led10, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(50, rmii, aud_pin, wifi0, wifi1, led11, NA, NA, NA, NA, NA,
NA, NA, NA, NA),
PINGROUP(51, rmii, aud_pin, wifi0, wifi1, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA),
PINGROUP(52, qpic, mdc, pcie, i2s_tx, NA, NA, NA, tm, wifi0, wifi1, NA,
NA, NA, NA),
PINGROUP(53, qpic, mdio, i2s_tx, prng_rosc, NA, tm, wifi0, wifi1, NA,
NA, NA, NA, NA, NA),
PINGROUP(54, qpic, blsp_spi0, i2s_td, NA, pmu, NA, NA, NA, tm, NA, NA,
NA, NA, NA),
PINGROUP(55, qpic, blsp_spi0, i2s_td, NA, pmu, NA, NA, NA, tm, NA, NA,
NA, NA, NA),
PINGROUP(56, qpic, blsp_spi0, i2s_td, NA, NA, tm, wifi0, wifi1, NA, NA,
NA, NA, NA, NA),
PINGROUP(57, qpic, blsp_spi0, i2s_tx, NA, NA, tm, wifi0, wifi1, NA, NA,
NA, NA, NA, NA),
PINGROUP(58, qpic, led2, blsp_i2c0, smart3, smart1, i2s_rx, NA, NA, tm,
wifi0, wifi1, NA, NA, NA),
PINGROUP(59, qpic, blsp_i2c0, smart3, smart1, i2s_spdif_in, NA, NA, NA,
NA, NA, tm, NA, NA, NA),
PINGROUP(60, qpic, blsp_uart0, smart1, smart3, led0, i2s_tx, i2s_rx,
NA, NA, NA, NA, NA, tm, NA),
PINGROUP(61, qpic, blsp_uart0, smart1, smart3, led1, i2s_tx, i2s_rx,
NA, NA, NA, NA, NA, tm, NA),
PINGROUP(62, qpic, chip_rst, NA, NA, i2s_spdif_out, NA, NA, NA, NA, NA,
tm, NA, NA, NA),
PINGROUP(63, qpic, NA, NA, NA, i2s_td, i2s_rx, i2s_spdif_out,
i2s_spdif_in, NA, NA, NA, NA, tm, NA),
PINGROUP(64, qpic, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(65, qpic, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(66, qpic, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(67, qpic, audio_pwm, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA),
PINGROUP(68, qpic, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(69, qpic, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(70, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(71, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(72, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(73, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(74, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(76, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(77, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(78, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(79, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(82, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(83, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(84, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(85, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(88, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(89, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(90, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(91, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(92, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(93, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(94, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(95, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(96, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(97, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
PINGROUP(98, wifi0, wifi1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA),
PINGROUP(99, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
};
static const char *ipq4019_get_function_name(struct udevice *dev,
unsigned int selector)
{
@@ -36,14 +308,22 @@ static const char *ipq4019_get_function_name(struct udevice *dev,
static const char *ipq4019_get_pin_name(struct udevice *dev,
unsigned int selector)
{
snprintf(pin_name, MAX_PIN_NAME_LEN, "GPIO_%u", selector);
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
return pin_name;
}
static unsigned int ipq4019_get_function_mux(__maybe_unused unsigned int pin,
static unsigned int ipq4019_get_function_mux(unsigned int pin,
unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
unsigned int i;
const msm_pin_function *func = ipq4019_pin_functions + pin;
for (i = 0; i < 15; i++)
if ((*func)[i] == selector)
return i;
pr_err("Can't find requested function for pin %u pin\n", pin);
return -EINVAL;
}
static const struct msm_pinctrl_data ipq4019_data = {
@@ -68,4 +348,5 @@ U_BOOT_DRIVER(pinctrl_ipq4019) = {
.of_match = msm_pinctrl_ids,
.ops = &msm_pinctrl_ops,
.bind = msm_pinctrl_bind,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@@ -0,0 +1,70 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Qualcomm qcm2290 pinctrl
*
* (C) Copyright 2024 Linaro Ltd.
*
*/
#include <dm.h>
#include "pinctrl-qcom.h"
#define MAX_PIN_NAME_LEN 32
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
static const struct pinctrl_function msm_pinctrl_functions[] = {
{ "qup4", 1 },
{ "gpio", 0 },
};
static const char *qcm2290_get_function_name(struct udevice *dev, unsigned int selector)
{
return msm_pinctrl_functions[selector].name;
}
static const char *qcm2290_get_pin_name(struct udevice *dev, unsigned int selector)
{
static const char *const special_pins_names[] = {
"sdc1_rclk", "sdc1_clk", "sdc1_cmd", "sdc1_data",
"sdc2_clk", "sdc2_cmd", "sdc2_data",
};
if (selector >= 127 && selector <= 133)
snprintf(pin_name, MAX_PIN_NAME_LEN, special_pins_names[selector - 127]);
else
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
return pin_name;
}
static unsigned int qcm2290_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
struct msm_pinctrl_data qcm2290_data = {
.pin_data = {
.pin_count = 133,
.special_pins_start = 127,
},
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
.get_function_name = qcm2290_get_function_name,
.get_function_mux = qcm2290_get_function_mux,
.get_pin_name = qcm2290_get_pin_name,
};
static const struct udevice_id msm_pinctrl_ids[] = {
{
.compatible = "qcom,qcm2290-tlmm",
.data = (ulong)&qcm2290_data
},
{ /* Sentinel */ } };
U_BOOT_DRIVER(pinctrl_qcm2290) = {
.name = "pinctrl_qcm2290",
.id = UCLASS_NOP,
.of_match = msm_pinctrl_ids,
.ops = &msm_pinctrl_ops,
.bind = msm_pinctrl_bind,
};

View File

@@ -29,15 +29,24 @@ struct msm_pinctrl_priv {
#define GPIO_CONFIG_REG(priv, x) \
(qcom_pin_offset((priv)->data->pin_data.pin_offsets, x))
#define GPIO_IN_OUT_REG(priv, x) \
(GPIO_CONFIG_REG(priv, x) + 0x4)
#define TLMM_GPIO_PULL_MASK GENMASK(1, 0)
#define TLMM_FUNC_SEL_MASK GENMASK(5, 2)
#define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6)
#define TLMM_GPIO_DISABLE BIT(9)
#define TLMM_GPIO_OUTPUT_MASK BIT(1)
#define TLMM_GPIO_OE_MASK BIT(9)
/* GPIO register shifts. */
#define GPIO_OUT_SHIFT 1
static const struct pinconf_param msm_conf_params[] = {
{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 2 },
{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 3 },
{ "output-high", PIN_CONFIG_OUTPUT, 1, },
{ "output-low", PIN_CONFIG_OUTPUT, 0, },
};
static int msm_get_functions_count(struct udevice *dev)
@@ -90,7 +99,7 @@ static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector,
return 0;
clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE, func << 2);
TLMM_FUNC_SEL_MASK | TLMM_GPIO_OE_MASK, func << 2);
return 0;
}
@@ -117,6 +126,12 @@ static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector,
clrsetbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
TLMM_GPIO_PULL_MASK, argument);
break;
case PIN_CONFIG_OUTPUT:
writel(argument << GPIO_OUT_SHIFT,
priv->base + GPIO_IN_OUT_REG(priv, pin_selector));
setbits_le32(priv->base + GPIO_CONFIG_REG(priv, pin_selector),
TLMM_GPIO_OE_MASK);
break;
default:
return 0;
}

View File

@@ -66,7 +66,18 @@ static const char *sdm845_get_function_name(struct udevice *dev,
static const char *sdm845_get_pin_name(struct udevice *dev,
unsigned int selector)
{
static const char *special_pins_names[] = {
"ufs_reset",
"sdc2_clk",
"sdc2_cmd",
"sdc2_data",
};
if (selector >= 150 && selector <= 154)
snprintf(pin_name, MAX_PIN_NAME_LEN, special_pins_names[selector - 150]);
else
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
return pin_name;
}

View File

@@ -0,0 +1,200 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Qualcomm sm6115 pinctrl
*
* (C) Copyright 2024 Linaro Ltd.
*
*/
#include <dm.h>
#include "pinctrl-qcom.h"
#define WEST 0x00000000
#define SOUTH 0x00400000
#define EAST 0x00800000
#define MAX_PIN_NAME_LEN 32
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
static const struct pinctrl_function msm_pinctrl_functions[] = {
{ "qup4", 1 },
{ "gpio", 0 },
};
static const unsigned int sm6115_pin_offsets[] = {
[0] = WEST,
[1] = WEST,
[2] = WEST,
[3] = WEST,
[4] = WEST,
[5] = WEST,
[6] = WEST,
[7] = WEST,
[8] = EAST,
[9] = EAST,
[10] = EAST,
[11] = EAST,
[12] = WEST,
[13] = WEST,
[14] = WEST,
[15] = WEST,
[16] = WEST,
[17] = WEST,
[18] = EAST,
[19] = EAST,
[20] = EAST,
[21] = EAST,
[22] = EAST,
[23] = EAST,
[24] = EAST,
[25] = EAST,
[26] = EAST,
[27] = EAST,
[28] = EAST,
[29] = EAST,
[30] = EAST,
[31] = EAST,
[32] = EAST,
[33] = EAST,
[34] = EAST,
[35] = EAST,
[36] = EAST,
[37] = EAST,
[38] = EAST,
[39] = EAST,
[40] = EAST,
[41] = EAST,
[42] = EAST,
[43] = EAST,
[44] = EAST,
[45] = EAST,
[46] = EAST,
[47] = EAST,
[48] = EAST,
[49] = EAST,
[50] = EAST,
[51] = EAST,
[52] = EAST,
[53] = EAST,
[54] = EAST,
[55] = EAST,
[56] = EAST,
[57] = EAST,
[58] = EAST,
[59] = EAST,
[60] = EAST,
[61] = EAST,
[62] = EAST,
[63] = EAST,
[64] = EAST,
[65] = WEST,
[66] = WEST,
[67] = WEST,
[68] = WEST,
[69] = WEST,
[70] = WEST,
[71] = WEST,
[72] = SOUTH,
[73] = SOUTH,
[74] = SOUTH,
[75] = SOUTH,
[76] = SOUTH,
[77] = SOUTH,
[78] = SOUTH,
[79] = SOUTH,
[80] = WEST,
[81] = WEST,
[82] = WEST,
[83] = WEST,
[84] = WEST,
[85] = WEST,
[86] = WEST,
[87] = EAST,
[88] = EAST,
[89] = WEST,
[90] = EAST,
[91] = EAST,
[92] = WEST,
[93] = WEST,
[94] = WEST,
[95] = WEST,
[96] = WEST,
[97] = WEST,
[98] = SOUTH,
[99] = SOUTH,
[100] = SOUTH,
[101] = SOUTH,
[102] = SOUTH,
[103] = SOUTH,
[104] = SOUTH,
[105] = SOUTH,
[106] = SOUTH,
[107] = SOUTH,
[108] = SOUTH,
[109] = SOUTH,
[110] = SOUTH,
[111] = SOUTH,
[112] = SOUTH,
/* Special pins */
[113] = 0,
[114] = 0,
[115] = 0,
[116] = 0,
[117] = 0,
[118] = 0,
[119] = 0,
[120] = 0,
};
static const char *sm6115_get_function_name(struct udevice *dev, unsigned int selector)
{
return msm_pinctrl_functions[selector].name;
}
static const char *sm6115_get_pin_name(struct udevice *dev, unsigned int selector)
{
static const char *special_pins_names[] = {
"ufs_reset", "sdc1_rclk", "sdc1_clk", "sdc1_cmd",
"sdc1_data", "sdc2_clk", "sdc2_cmd", "sdc2_data",
};
if (selector >= 113 && selector <= 120)
snprintf(pin_name, MAX_PIN_NAME_LEN, special_pins_names[selector - 113]);
else
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
return pin_name;
}
static unsigned int sm6115_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
struct msm_pinctrl_data sm6115_data = {
.pin_data = {
.pin_offsets = sm6115_pin_offsets,
.pin_count = ARRAY_SIZE(sm6115_pin_offsets),
.special_pins_start = 113,
},
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
.get_function_name = sm6115_get_function_name,
.get_function_mux = sm6115_get_function_mux,
.get_pin_name = sm6115_get_pin_name,
};
static const struct udevice_id msm_pinctrl_ids[] = {
{
.compatible = "qcom,sm6115-tlmm",
.data = (ulong)&sm6115_data
},
{ /* Sentinel */ } };
U_BOOT_DRIVER(pinctrl_sm6115) = {
.name = "pinctrl_sm6115",
.id = UCLASS_NOP,
.of_match = msm_pinctrl_ids,
.ops = &msm_pinctrl_ops,
.bind = msm_pinctrl_bind,
};

View File

@@ -0,0 +1,99 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Qualcomm sm8250 pinctrl
*
* (C) Copyright 2024 Linaro Ltd.
*
*/
#include <dm.h>
#include "pinctrl-qcom.h"
#define WEST 0x00000000
#define SOUTH 0x00400000
#define NORTH 0x00800000
#define MAX_PIN_NAME_LEN 32
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
static const struct pinctrl_function msm_pinctrl_functions[] = { { "qup12", 1 },
{ "gpio", 0 },
{ "sdc2_clk", 0 } };
static const unsigned int sm8250_pin_offsets[] = {
[0] = SOUTH, [1] = SOUTH, [2] = SOUTH, [3] = SOUTH, [4] = NORTH, [5] = NORTH,
[6] = NORTH, [7] = NORTH, [8] = NORTH, [9] = NORTH, [10] = NORTH, [11] = NORTH,
[12] = NORTH, [13] = NORTH, [14] = NORTH, [15] = NORTH, [16] = NORTH, [17] = NORTH,
[18] = NORTH, [19] = NORTH, [20] = NORTH, [21] = NORTH, [22] = NORTH, [23] = NORTH,
[24] = SOUTH, [25] = SOUTH, [26] = SOUTH, [27] = SOUTH, [28] = NORTH, [29] = NORTH,
[30] = NORTH, [31] = NORTH, [32] = SOUTH, [33] = SOUTH, [34] = SOUTH, [35] = SOUTH,
[36] = SOUTH, [37] = SOUTH, [38] = SOUTH, [39] = SOUTH, [40] = SOUTH, [41] = SOUTH,
[42] = SOUTH, [43] = SOUTH, [44] = SOUTH, [45] = SOUTH, [46] = SOUTH, [47] = SOUTH,
[48] = SOUTH, [49] = SOUTH, [50] = SOUTH, [51] = SOUTH, [52] = SOUTH, [53] = SOUTH,
[54] = SOUTH, [55] = SOUTH, [56] = SOUTH, [57] = SOUTH, [58] = SOUTH, [59] = SOUTH,
[60] = SOUTH, [61] = SOUTH, [62] = SOUTH, [63] = SOUTH, [64] = SOUTH, [65] = SOUTH,
[66] = NORTH, [67] = NORTH, [68] = NORTH, [69] = SOUTH, [70] = SOUTH, [71] = SOUTH,
[72] = SOUTH, [73] = SOUTH, [74] = SOUTH, [75] = SOUTH, [76] = SOUTH, [77] = NORTH,
[78] = NORTH, [79] = NORTH, [80] = NORTH, [81] = NORTH, [82] = NORTH, [83] = NORTH,
[84] = NORTH, [85] = SOUTH, [86] = SOUTH, [87] = SOUTH, [88] = SOUTH, [89] = SOUTH,
[90] = SOUTH, [91] = SOUTH, [92] = NORTH, [93] = NORTH, [94] = NORTH, [95] = NORTH,
[96] = NORTH, [97] = NORTH, [98] = NORTH, [99] = NORTH, [100] = NORTH, [101] = NORTH,
[102] = NORTH, [103] = NORTH, [104] = NORTH, [105] = NORTH, [106] = NORTH, [107] = NORTH,
[108] = NORTH, [109] = NORTH, [110] = NORTH, [111] = NORTH, [112] = NORTH, [113] = NORTH,
[114] = NORTH, [115] = NORTH, [116] = NORTH, [117] = NORTH, [118] = NORTH, [119] = NORTH,
[120] = NORTH, [121] = NORTH, [122] = NORTH, [123] = NORTH, [124] = NORTH, [125] = SOUTH,
[126] = SOUTH, [127] = SOUTH, [128] = SOUTH, [129] = SOUTH, [130] = SOUTH, [131] = SOUTH,
[132] = SOUTH, [133] = WEST, [134] = WEST, [135] = WEST, [136] = WEST, [137] = WEST,
[138] = WEST, [139] = WEST, [140] = WEST, [141] = WEST, [142] = WEST, [143] = WEST,
[144] = WEST, [145] = WEST, [146] = WEST, [147] = WEST, [148] = WEST, [149] = WEST,
[150] = WEST, [151] = WEST, [152] = WEST, [153] = WEST, [154] = WEST, [155] = WEST,
[156] = WEST, [157] = WEST, [158] = WEST, [159] = WEST, [160] = WEST, [161] = WEST,
[162] = WEST, [163] = WEST, [164] = WEST, [165] = WEST, [166] = WEST, [167] = WEST,
[168] = WEST, [169] = WEST, [170] = WEST, [171] = WEST, [172] = WEST, [173] = WEST,
[174] = WEST, [175] = WEST, [176] = WEST, [177] = WEST, [178] = WEST, [179] = WEST,
[180] = 0, [181] = 0, [182] = 0, [183] = 0,
};
static const char *sm8250_get_function_name(struct udevice *dev, unsigned int selector)
{
return msm_pinctrl_functions[selector].name;
}
static const char *sm8250_get_pin_name(struct udevice *dev, unsigned int selector)
{
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
return pin_name;
}
static unsigned int sm8250_get_function_mux(__maybe_unused unsigned int pin, unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
static struct msm_pinctrl_data sm8250_data = {
.pin_data = {
.pin_offsets = sm8250_pin_offsets,
.pin_count = ARRAY_SIZE(sm8250_pin_offsets),
.special_pins_start = 180,
},
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
.get_function_name = sm8250_get_function_name,
.get_function_mux = sm8250_get_function_mux,
.get_pin_name = sm8250_get_pin_name,
};
static const struct udevice_id msm_pinctrl_ids[] = {
{
.compatible = "qcom,sm8250-pinctrl",
.data = (ulong)&sm8250_data
},
{ /* Sentinel */ } };
U_BOOT_DRIVER(pinctrl_sm8250) = {
.name = "pinctrl_sm8250",
.id = UCLASS_NOP,
.of_match = msm_pinctrl_ids,
.ops = &msm_pinctrl_ops,
.bind = msm_pinctrl_bind,
};

View File

@@ -0,0 +1,74 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Qualcomm sm8550 pinctrl
*
* (C) Copyright 2024 Linaro Ltd.
*
*/
#include <dm.h>
#include "pinctrl-qcom.h"
#define MAX_PIN_NAME_LEN 32
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
static const struct pinctrl_function msm_pinctrl_functions[] = {
{"qup1_se7", 1},
{"gpio", 0},
};
static const char *sm8550_get_function_name(struct udevice *dev,
unsigned int selector)
{
return msm_pinctrl_functions[selector].name;
}
static const char *sm8550_get_pin_name(struct udevice *dev,
unsigned int selector)
{
static const char *special_pins_names[] = {
"ufs_reset",
"sdc2_clk",
"sdc2_cmd",
"sdc2_data",
};
if (selector >= 210 && selector <= 213)
snprintf(pin_name, MAX_PIN_NAME_LEN, special_pins_names[selector - 210]);
else
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
return pin_name;
}
static unsigned int sm8550_get_function_mux(__maybe_unused unsigned int pin,
unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
static struct msm_pinctrl_data sm8550_data = {
.pin_data = {
.pin_count = 214,
.special_pins_start = 210,
},
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
.get_function_name = sm8550_get_function_name,
.get_function_mux = sm8550_get_function_mux,
.get_pin_name = sm8550_get_pin_name,
};
static const struct udevice_id msm_pinctrl_ids[] = {
{ .compatible = "qcom,sm8550-tlmm", .data = (ulong)&sm8550_data },
{ /* Sentinel */ }
};
U_BOOT_DRIVER(pinctrl_sm8550) = {
.name = "pinctrl_sm8550",
.id = UCLASS_NOP,
.of_match = msm_pinctrl_ids,
.ops = &msm_pinctrl_ops,
.bind = msm_pinctrl_bind,
};

View File

@@ -0,0 +1,74 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Qualcomm sm8650 pinctrl
*
* (C) Copyright 2024 Linaro Ltd.
*
*/
#include <dm.h>
#include "pinctrl-qcom.h"
#define MAX_PIN_NAME_LEN 32
static char pin_name[MAX_PIN_NAME_LEN] __section(".data");
static const struct pinctrl_function msm_pinctrl_functions[] = {
{"qup2_se7", 1},
{"gpio", 0},
};
static const char *sm8650_get_function_name(struct udevice *dev,
unsigned int selector)
{
return msm_pinctrl_functions[selector].name;
}
static const char *sm8650_get_pin_name(struct udevice *dev,
unsigned int selector)
{
static const char *special_pins_names[] = {
"ufs_reset",
"sdc2_clk",
"sdc2_cmd",
"sdc2_data",
};
if (selector >= 210 && selector <= 213)
snprintf(pin_name, MAX_PIN_NAME_LEN, special_pins_names[selector - 210]);
else
snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector);
return pin_name;
}
static unsigned int sm8650_get_function_mux(__maybe_unused unsigned int pin,
unsigned int selector)
{
return msm_pinctrl_functions[selector].val;
}
static struct msm_pinctrl_data sm8650_data = {
.pin_data = {
.pin_count = 214,
.special_pins_start = 210,
},
.functions_count = ARRAY_SIZE(msm_pinctrl_functions),
.get_function_name = sm8650_get_function_name,
.get_function_mux = sm8650_get_function_mux,
.get_pin_name = sm8650_get_pin_name,
};
static const struct udevice_id msm_pinctrl_ids[] = {
{ .compatible = "qcom,sm8650-tlmm", .data = (ulong)&sm8650_data },
{ /* Sentinel */ }
};
U_BOOT_DRIVER(pinctrl_sm8650) = {
.name = "pinctrl_sm8650",
.id = UCLASS_NOP,
.of_match = msm_pinctrl_ids,
.ops = &msm_pinctrl_ops,
.bind = msm_pinctrl_bind,
};

View File

@@ -321,7 +321,7 @@ config DEBUG_UART_S5P
config DEBUG_UART_MSM
bool "Qualcomm QUP UART debug"
depends on ARCH_SNAPDRAGON
depends on ARCH_SNAPDRAGON || ARCH_IPQ40XX
help
Select this to enable a debug UART using the serial_msm driver. You
will need to provide parameters to make this work. The driver will

View File

@@ -32,6 +32,16 @@
#define UARTDM_RXFS_BUF_MASK 0x7
#define UARTDM_MR1 0x00
#define UARTDM_MR2 0x04
/*
* This is documented on page 1817 of the apq8016e technical reference manual.
* section 6.2.5.3.26
*
* The upper nybble contains the bit clock divider for the RX pin, the lower
* nybble defines the TX pin. In almost all cases these should be the same value.
*
* The baud rate is the core clock frequency divided by the fixed divider value
* programmed into this register (defined in calc_csr_bitrate()).
*/
#define UARTDM_CSR 0xA0
#define UARTDM_SR 0xA4 /* Status register */
@@ -53,10 +63,10 @@
#define UARTDM_TF 0x100 /* UART Transmit FIFO register */
#define UARTDM_RF 0x140 /* UART Receive FIFO register */
#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
#define MSM_BOOT_UART_DM_8_N_1_MODE 0x34
#define MSM_BOOT_UART_DM_CMD_RESET_RX 0x10
#define MSM_BOOT_UART_DM_CMD_RESET_TX 0x20
#define MSM_UART_MR1_RX_RDY_CTL BIT(7)
DECLARE_GLOBAL_DATA_PTR;
@@ -64,7 +74,7 @@ struct msm_serial_data {
phys_addr_t base;
unsigned chars_cnt; /* number of buffered chars */
uint32_t chars_buf; /* buffered chars */
uint32_t clk_bit_rate; /* data mover mode bit rate register value */
uint32_t clk_rate; /* core clock rate */
};
static int msm_serial_fetch(struct udevice *dev)
@@ -156,33 +166,63 @@ static const struct dm_serial_ops msm_serial_ops = {
.getc = msm_serial_getc,
};
static int msm_uart_clk_init(struct udevice *dev)
static long msm_uart_clk_init(struct udevice *dev)
{
uint clk_rate = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
"clock-frequency", 115200);
struct msm_serial_data *priv = dev_get_priv(dev);
struct clk clk;
int ret;
long rate;
ret = clk_get_by_name(dev, "core", &clk);
if (ret < 0) {
pr_warn("%s: Failed to get clock: %d\n", __func__, ret);
return ret;
return 0;
}
ret = clk_set_rate(&clk, clk_rate);
if (ret < 0)
return ret;
rate = clk_set_rate(&clk, priv->clk_rate);
return 0;
return rate;
}
static int calc_csr_bitrate(struct msm_serial_data *priv)
{
/* This table is from the TRE. See the definition of UARTDM_CSR */
unsigned int csr_div_table[] = {24576, 12288, 6144, 3072, 1536, 768, 512, 384,
256, 192, 128, 96, 64, 48, 32, 16};
int i = ARRAY_SIZE(csr_div_table) - 1;
/* Currently we only support one baudrate */
int baud = 115200;
for (; i >= 0; i--) {
int x = priv->clk_rate / csr_div_table[i];
if (x == baud)
/* Duplicate the configuration for RX
* as the lower nybble only configures TX
*/
return i + (i << 4);
}
return -EINVAL;
}
static void uart_dm_init(struct msm_serial_data *priv)
{
/* Delay initialization for a bit to let pins stabilize if necessary */
mdelay(5);
int bitrate = calc_csr_bitrate(priv);
if (bitrate < 0) {
log_warning("Couldn't calculate bit clock divider! Using default\n");
/* This happens to be the value used on MSM8916 for the hardcoded clockrate
* in clock-apq8016. It's at least a better guess than a value we *know*
* is wrong...
*/
bitrate = 0xCC;
}
writel(priv->clk_bit_rate, priv->base + UARTDM_CSR);
writel(0x0, priv->base + UARTDM_MR1);
writel(bitrate, priv->base + UARTDM_CSR);
/* Enable RS232 flow control to support RS232 db9 connector */
writel(MSM_UART_MR1_RX_RDY_CTL, priv->base + UARTDM_MR1);
writel(MSM_BOOT_UART_DM_8_N_1_MODE, priv->base + UARTDM_MR2);
writel(MSM_BOOT_UART_DM_CMD_RESET_RX, priv->base + UARTDM_CR);
writel(MSM_BOOT_UART_DM_CMD_RESET_TX, priv->base + UARTDM_CR);
@@ -192,16 +232,25 @@ static void uart_dm_init(struct msm_serial_data *priv)
}
static int msm_serial_probe(struct udevice *dev)
{
int ret;
struct msm_serial_data *priv = dev_get_priv(dev);
long rate;
/* No need to reinitialize the UART after relocation */
if (gd->flags & GD_FLG_RELOC)
return 0;
ret = msm_uart_clk_init(dev);
if (ret)
return ret;
rate = msm_uart_clk_init(dev);
if (rate < 0)
return rate;
if (!rate) {
log_err("Got core clock rate of 0... Please fix your clock driver\n");
return -EINVAL;
}
/* Update the clock rate to the actual programmed rate returned by the
* clock driver
*/
priv->clk_rate = rate;
uart_dm_init(priv);
@@ -211,13 +260,18 @@ static int msm_serial_probe(struct udevice *dev)
static int msm_serial_of_to_plat(struct udevice *dev)
{
struct msm_serial_data *priv = dev_get_priv(dev);
int ret;
priv->base = dev_read_addr(dev);
if (priv->base == FDT_ADDR_T_NONE)
return -EINVAL;
priv->clk_bit_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"bit-rate", UART_DM_CLK_RX_TX_BIT_RATE);
ret = dev_read_u32(dev, "clock-frequency", &priv->clk_rate);
if (ret < 0) {
log_debug("No clock frequency specified, using default rate\n");
/* Default for APQ8016 */
priv->clk_rate = 7372800;
}
return 0;
}
@@ -242,18 +296,23 @@ U_BOOT_DRIVER(serial_msm) = {
static struct msm_serial_data init_serial_data = {
.base = CONFIG_VAL(DEBUG_UART_BASE),
.clk_rate = 7372800,
.clk_rate = CONFIG_VAL(DEBUG_UART_CLOCK),
};
#include <debug_uart.h>
/* Uncomment to turn on UART clocks when debugging U-Boot as aboot on MSM8916 */
//int apq8016_clk_init_uart(phys_addr_t gcc_base);
//int apq8016_clk_init_uart(phys_addr_t gcc_base, unsigned long id);
static inline void _debug_uart_init(void)
{
/* Uncomment to turn on UART clocks when debugging U-Boot as aboot on MSM8916 */
//apq8016_clk_init_uart(0x1800000);
/*
* Uncomment to turn on UART clocks when debugging U-Boot as aboot
* on MSM8916. Supported debug UART clock IDs:
* - db410c: GCC_BLSP1_UART2_APPS_CLK
* - HMIBSC: GCC_BLSP1_UART1_APPS_CLK
*/
//apq8016_clk_init_uart(0x1800000, <uart_clk_id>);
uart_dm_init(&init_serial_data);
}

View File

@@ -23,13 +23,19 @@ DECLARE_GLOBAL_DATA_PTR;
#define PMIC_ARB_VERSION_V2_MIN 0x20010000
#define PMIC_ARB_VERSION_V3_MIN 0x30000000
#define PMIC_ARB_VERSION_V5_MIN 0x50000000
#define PMIC_ARB_VERSION_V7_MIN 0x70000000
#define APID_MAP_OFFSET_V1_V2_V3 (0x800)
#define APID_MAP_OFFSET_V5 (0x900)
#define APID_MAP_OFFSET_V7 (0x2000)
#define ARB_CHANNEL_OFFSET(n) (0x4 * (n))
#define SPMI_CH_OFFSET(chnl) ((chnl) * 0x8000)
#define SPMI_V5_OBS_CH_OFFSET(chnl) ((chnl) * 0x80)
#define SPMI_V7_OBS_CH_OFFSET(chnl) ((chnl) * 0x20)
#define SPMI_V5_RW_CH_OFFSET(chnl) ((chnl) * 0x10000)
#define SPMI_V7_RW_CH_OFFSET(chnl) ((chnl) * 0x1000)
#define SPMI_OWNERSHIP_PERIPH2OWNER(x) ((x) & 0x7)
#define SPMI_REG_CMD0 0x0
#define SPMI_REG_CONFIG 0x4
@@ -49,14 +55,20 @@ DECLARE_GLOBAL_DATA_PTR;
#define SPMI_STATUS_DONE 0x1
#define SPMI_MAX_CHANNELS 128
#define SPMI_MAX_CHANNELS_V5 512
#define SPMI_MAX_CHANNELS_V7 1024
#define SPMI_MAX_SLAVES 16
#define SPMI_MAX_PERIPH 256
#define SPMI_CHANNEL_READ_ONLY BIT(31)
#define SPMI_CHANNEL_MASK 0xffff
enum arb_ver {
V1 = 1,
V2,
V3,
V5 = 5
V5 = 5,
V7 = 7
};
/*
@@ -72,12 +84,25 @@ struct msm_spmi_priv {
phys_addr_t arb_chnl; /* ARB channel mapping base */
phys_addr_t spmi_chnls; /* SPMI channels */
phys_addr_t spmi_obs; /* SPMI observer */
phys_addr_t spmi_cnfg; /* SPMI config */
u32 owner; /* Current owner */
unsigned int max_channels; /* Max channels */
/* SPMI channel map */
uint8_t channel_map[SPMI_MAX_SLAVES][SPMI_MAX_PERIPH];
uint32_t channel_map[SPMI_MAX_SLAVES][SPMI_MAX_PERIPH];
/* SPMI bus arbiter version */
u32 arb_ver;
};
static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u8 pid, u8 off)
{
return (opc << 27) | (sid << 20) | (pid << 12) | (off << 4) | 1;
}
static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 off)
{
return (opc << 27) | (off << 4) | 1;
}
static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off,
uint8_t val)
{
@@ -90,35 +115,53 @@ static int msm_spmi_write(struct udevice *dev, int usid, int pid, int off,
return -EIO;
if (pid >= SPMI_MAX_PERIPH)
return -EIO;
if (priv->channel_map[usid][pid] & SPMI_CHANNEL_READ_ONLY)
return -EPERM;
channel = priv->channel_map[usid][pid];
channel = priv->channel_map[usid][pid] & SPMI_CHANNEL_MASK;
/* Disable IRQ mode for the current channel*/
writel(0x0,
priv->spmi_chnls + SPMI_CH_OFFSET(channel) + SPMI_REG_CONFIG);
dev_dbg(dev, "[%d:%d] %s: channel %d\n", usid, pid, __func__, channel);
/* Write single byte */
writel(val, priv->spmi_chnls + SPMI_CH_OFFSET(channel) + SPMI_REG_WDATA);
/* Prepare write command */
reg |= SPMI_CMD_EXT_REG_WRITE_LONG << SPMI_CMD_OPCODE_SHIFT;
reg |= (usid << SPMI_CMD_SLAVE_ID_SHIFT);
reg |= (pid << SPMI_CMD_ADDR_SHIFT);
reg |= (off << SPMI_CMD_ADDR_OFFSET_SHIFT);
reg |= 1; /* byte count */
if (priv->arb_ver == V5)
ch_offset = SPMI_V5_RW_CH_OFFSET(channel);
else
switch (priv->arb_ver) {
case V1:
ch_offset = SPMI_CH_OFFSET(channel);
reg = pmic_arb_fmt_cmd_v1(SPMI_CMD_EXT_REG_WRITE_LONG,
usid, pid, off);
break;
case V2:
ch_offset = SPMI_CH_OFFSET(channel);
reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_WRITE_LONG, off);
break;
case V5:
ch_offset = SPMI_V5_RW_CH_OFFSET(channel);
reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_WRITE_LONG, off);
break;
case V7:
ch_offset = SPMI_V7_RW_CH_OFFSET(channel);
reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_WRITE_LONG, off);
break;
}
/* Disable IRQ mode for the current channel*/
writel(0x0, priv->spmi_chnls + ch_offset + SPMI_REG_CONFIG);
/* Write single byte */
writel(val, priv->spmi_chnls + ch_offset + SPMI_REG_WDATA);
/* Send write command */
writel(reg, priv->spmi_chnls + SPMI_CH_OFFSET(channel) + SPMI_REG_CMD0);
writel(reg, priv->spmi_chnls + ch_offset + SPMI_REG_CMD0);
/* Wait till CMD DONE status */
reg = 0;
while (!reg) {
reg = readl(priv->spmi_chnls + SPMI_CH_OFFSET(channel) +
reg = readl(priv->spmi_chnls + ch_offset +
SPMI_REG_STATUS);
}
@@ -142,23 +185,44 @@ static int msm_spmi_read(struct udevice *dev, int usid, int pid, int off)
if (pid >= SPMI_MAX_PERIPH)
return -EIO;
channel = priv->channel_map[usid][pid];
channel = priv->channel_map[usid][pid] & SPMI_CHANNEL_MASK;
if (priv->arb_ver == V5)
ch_offset = SPMI_V5_OBS_CH_OFFSET(channel);
else
dev_dbg(dev, "[%d:%d] %s: channel %d\n", usid, pid, __func__, channel);
switch (priv->arb_ver) {
case V1:
ch_offset = SPMI_CH_OFFSET(channel);
/* Prepare read command */
reg = pmic_arb_fmt_cmd_v1(SPMI_CMD_EXT_REG_READ_LONG,
usid, pid, off);
break;
case V2:
ch_offset = SPMI_CH_OFFSET(channel);
/* Prepare read command */
reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_READ_LONG, off);
break;
case V5:
ch_offset = SPMI_V5_OBS_CH_OFFSET(channel);
/* Prepare read command */
reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_READ_LONG, off);
break;
case V7:
ch_offset = SPMI_V7_OBS_CH_OFFSET(channel);
/* Prepare read command */
reg = pmic_arb_fmt_cmd_v2(SPMI_CMD_EXT_REG_READ_LONG, off);
break;
}
/* Disable IRQ mode for the current channel*/
writel(0x0, priv->spmi_obs + ch_offset + SPMI_REG_CONFIG);
/* Prepare read command */
reg |= SPMI_CMD_EXT_REG_READ_LONG << SPMI_CMD_OPCODE_SHIFT;
reg |= (usid << SPMI_CMD_SLAVE_ID_SHIFT);
reg |= (pid << SPMI_CMD_ADDR_SHIFT);
reg |= (off << SPMI_CMD_ADDR_OFFSET_SHIFT);
reg |= 1; /* byte count */
/* Request read */
writel(reg, priv->spmi_obs + ch_offset + SPMI_REG_CMD0);
@@ -193,18 +257,29 @@ static int msm_spmi_probe(struct udevice *dev)
core_addr = dev_read_addr_name(dev, "core");
priv->spmi_chnls = dev_read_addr_name(dev, "chnls");
priv->spmi_obs = dev_read_addr_name(dev, "obsrvr");
dev_read_u32(dev, "qcom,ee", &priv->owner);
hw_ver = readl(core_addr + PMIC_ARB_VERSION);
if (hw_ver < PMIC_ARB_VERSION_V3_MIN) {
priv->arb_ver = V2;
priv->arb_chnl = core_addr + APID_MAP_OFFSET_V1_V2_V3;
priv->max_channels = SPMI_MAX_CHANNELS;
} else if (hw_ver < PMIC_ARB_VERSION_V5_MIN) {
priv->arb_ver = V3;
priv->arb_chnl = core_addr + APID_MAP_OFFSET_V1_V2_V3;
} else {
priv->max_channels = SPMI_MAX_CHANNELS;
} else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) {
priv->arb_ver = V5;
priv->arb_chnl = core_addr + APID_MAP_OFFSET_V5;
priv->max_channels = SPMI_MAX_CHANNELS;
priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg");
} else {
/* TOFIX: handle second bus */
priv->arb_ver = V7;
priv->arb_chnl = core_addr + APID_MAP_OFFSET_V7;
priv->max_channels = SPMI_MAX_CHANNELS_V7;
priv->spmi_cnfg = dev_read_addr_name(dev, "cnfg");
}
dev_dbg(dev, "PMIC Arb Version-%d (%#x)\n", hw_ver >> 28, hw_ver);
@@ -218,12 +293,21 @@ static int msm_spmi_probe(struct udevice *dev)
dev_dbg(dev, "priv->spmi_chnls address (%#08llx)\n", priv->spmi_chnls);
dev_dbg(dev, "priv->spmi_obs address (%#08llx)\n", priv->spmi_obs);
/* Scan peripherals connected to each SPMI channel */
for (i = 0; i < SPMI_MAX_PERIPH; i++) {
for (i = 0; i < priv->max_channels; i++) {
uint32_t periph = readl(priv->arb_chnl + ARB_CHANNEL_OFFSET(i));
uint8_t slave_id = (periph & 0xf0000) >> 16;
uint8_t pid = (periph & 0xff00) >> 8;
priv->channel_map[slave_id][pid] = i;
/* Mark channels read-only when from different owner */
if (priv->arb_ver == V5 || priv->arb_ver == V7) {
uint32_t cnfg = readl(priv->spmi_cnfg + ARB_CHANNEL_OFFSET(i));
uint8_t owner = SPMI_OWNERSHIP_PERIPH2OWNER(cnfg);
if (owner != priv->owner)
priv->channel_map[slave_id][pid] |= SPMI_CHANNEL_READ_ONLY;
}
}
return 0;
}

16
include/configs/hmibsc.h Normal file
View File

@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Board configuration file for HMIBSC
*
* (C) Copyright 2024 Sumit Garg <sumit.garg@linaro.org>
*/
#ifndef __CONFIGS_HMIBSC_H
#define __CONFIGS_HMIBSC_H
/* PHY needs a longer aneg time */
#define PHY_ANEG_TIMEOUT 8000
#define CFG_ENV_FLAGS_LIST_STATIC "BOOT_A_LEFT:dw,BOOT_B_LEFT:dw,BOOT_ORDER:sw"
#endif

265
include/soc/qcom/geni-se.h Normal file
View File

@@ -0,0 +1,265 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*/
#ifndef _QCOM_GENI_SE
#define _QCOM_GENI_SE
/* Protocols supported by GENI Serial Engines */
enum geni_se_protocol_type {
GENI_SE_NONE,
GENI_SE_SPI,
GENI_SE_UART,
GENI_SE_I2C,
GENI_SE_I3C,
GENI_SE_SPI_SLAVE,
};
#define QUP_HW_VER_REG 0x4
/* Common SE registers */
#define GENI_INIT_CFG_REVISION 0x0
#define GENI_S_INIT_CFG_REVISION 0x4
#define GENI_FORCE_DEFAULT_REG 0x20
#define GENI_OUTPUT_CTRL 0x24
#define GENI_CGC_CTRL 0x28
#define SE_GENI_STATUS 0x40
#define GENI_SER_M_CLK_CFG 0x48
#define GENI_SER_S_CLK_CFG 0x4c
#define GENI_IF_DISABLE_RO 0x64
#define GENI_FW_REVISION_RO 0x68
#define SE_GENI_CLK_SEL 0x7c
#define SE_GENI_CFG_SEQ_START 0x84
#define SE_GENI_BYTE_GRAN 0x254
#define SE_GENI_DMA_MODE_EN 0x258
#define SE_GENI_TX_PACKING_CFG0 0x260
#define SE_GENI_TX_PACKING_CFG1 0x264
#define SE_GENI_RX_PACKING_CFG0 0x284
#define SE_GENI_RX_PACKING_CFG1 0x288
#define SE_GENI_M_CMD0 0x600
#define SE_GENI_M_CMD_CTRL_REG 0x604
#define SE_GENI_M_IRQ_STATUS 0x610
#define SE_GENI_M_IRQ_EN 0x614
#define SE_GENI_M_IRQ_CLEAR 0x618
#define SE_GENI_S_CMD0 0x630
#define SE_GENI_S_CMD_CTRL_REG 0x634
#define SE_GENI_S_IRQ_STATUS 0x640
#define SE_GENI_S_IRQ_EN 0x644
#define SE_GENI_S_IRQ_CLEAR 0x648
#define SE_GENI_TX_FIFOn 0x700
#define SE_GENI_RX_FIFOn 0x780
#define SE_GENI_TX_FIFO_STATUS 0x800
#define SE_GENI_RX_FIFO_STATUS 0x804
#define SE_GENI_TX_WATERMARK_REG 0x80c
#define SE_GENI_RX_WATERMARK_REG 0x810
#define SE_GENI_RX_RFR_WATERMARK_REG 0x814
#define SE_GENI_IOS 0x908
#define SE_DMA_TX_IRQ_STAT 0xc40
#define SE_DMA_TX_IRQ_CLR 0xc44
#define SE_DMA_TX_FSM_RST 0xc58
#define SE_DMA_RX_IRQ_STAT 0xd40
#define SE_DMA_RX_IRQ_CLR 0xd44
#define SE_DMA_RX_LEN_IN 0xd54
#define SE_DMA_RX_FSM_RST 0xd58
#define SE_GSI_EVENT_EN 0xe18
#define SE_IRQ_EN 0xe1c
#define SE_HW_PARAM_0 0xe24
#define SE_HW_PARAM_1 0xe28
/* GENI_FORCE_DEFAULT_REG fields */
#define FORCE_DEFAULT BIT(0)
/* GENI_OUTPUT_CTRL fields */
#define GENI_IO_MUX_0_EN BIT(0)
#define DEFAULT_IO_OUTPUT_CTRL_MSK GENMASK(6, 0)
/* GENI_CGC_CTRL fields */
#define CFG_AHB_CLK_CGC_ON BIT(0)
#define CFG_AHB_WR_ACLK_CGC_ON BIT(1)
#define DATA_AHB_CLK_CGC_ON BIT(2)
#define SCLK_CGC_ON BIT(3)
#define TX_CLK_CGC_ON BIT(4)
#define RX_CLK_CGC_ON BIT(5)
#define EXT_CLK_CGC_ON BIT(6)
#define PROG_RAM_HCLK_OFF BIT(8)
#define PROG_RAM_SCLK_OFF BIT(9)
#define DEFAULT_CGC_EN GENMASK(6, 0)
/* GENI_STATUS fields */
#define M_GENI_CMD_ACTIVE BIT(0)
#define S_GENI_CMD_ACTIVE BIT(12)
/* GENI_SER_M_CLK_CFG/GENI_SER_S_CLK_CFG */
#define SER_CLK_EN BIT(0)
#define CLK_DIV_MSK GENMASK(15, 4)
#define CLK_DIV_SHFT 4
/* GENI_IF_DISABLE_RO fields */
#define FIFO_IF_DISABLE (BIT(0))
/* GENI_FW_REVISION_RO fields */
#define FW_REV_PROTOCOL_MSK GENMASK(15, 8)
#define FW_REV_PROTOCOL_SHFT 8
/* GENI_CLK_SEL fields */
#define CLK_SEL_MSK GENMASK(2, 0)
/* SE_GENI_CFG_SEQ_START fields */
#define START_TRIGGER BIT(0)
/* SE_IRQ_EN fields */
#define DMA_RX_IRQ_EN BIT(0)
#define DMA_TX_IRQ_EN BIT(1)
#define GENI_M_IRQ_EN BIT(2)
#define GENI_S_IRQ_EN BIT(3)
/* SE_GENI_DMA_MODE_EN */
#define GENI_DMA_MODE_EN BIT(0)
/* GENI_M_CMD0 fields */
#define M_OPCODE_MSK GENMASK(31, 27)
#define M_OPCODE_SHFT 27
#define M_PARAMS_MSK GENMASK(26, 0)
/* GENI_M_CMD_CTRL_REG */
#define M_GENI_CMD_CANCEL BIT(2)
#define M_GENI_CMD_ABORT BIT(1)
#define M_GENI_DISABLE BIT(0)
/* GENI_S_CMD0 fields */
#define S_OPCODE_MSK GENMASK(31, 27)
#define S_OPCODE_SHFT 27
#define S_PARAMS_MSK GENMASK(26, 0)
/* GENI_S_CMD_CTRL_REG */
#define S_GENI_CMD_CANCEL BIT(2)
#define S_GENI_CMD_ABORT BIT(1)
#define S_GENI_DISABLE BIT(0)
/* GENI_M_IRQ_EN fields */
#define M_CMD_DONE_EN BIT(0)
#define M_CMD_OVERRUN_EN BIT(1)
#define M_ILLEGAL_CMD_EN BIT(2)
#define M_CMD_FAILURE_EN BIT(3)
#define M_CMD_CANCEL_EN BIT(4)
#define M_CMD_ABORT_EN BIT(5)
#define M_TIMESTAMP_EN BIT(6)
#define M_RX_IRQ_EN BIT(7)
#define M_GP_SYNC_IRQ_0_EN BIT(8)
#define M_GP_IRQ_0_EN BIT(9)
#define M_GP_IRQ_1_EN BIT(10)
#define M_GP_IRQ_2_EN BIT(11)
#define M_GP_IRQ_3_EN BIT(12)
#define M_GP_IRQ_4_EN BIT(13)
#define M_GP_IRQ_5_EN BIT(14)
#define M_TX_FIFO_NOT_EMPTY_EN BIT(21)
#define M_IO_DATA_DEASSERT_EN BIT(22)
#define M_IO_DATA_ASSERT_EN BIT(23)
#define M_RX_FIFO_RD_ERR_EN BIT(24)
#define M_RX_FIFO_WR_ERR_EN BIT(25)
#define M_RX_FIFO_WATERMARK_EN BIT(26)
#define M_RX_FIFO_LAST_EN BIT(27)
#define M_TX_FIFO_RD_ERR_EN BIT(28)
#define M_TX_FIFO_WR_ERR_EN BIT(29)
#define M_TX_FIFO_WATERMARK_EN BIT(30)
#define M_SEC_IRQ_EN BIT(31)
#define M_COMMON_GENI_M_IRQ_EN (GENMASK(6, 1) | \
M_IO_DATA_DEASSERT_EN | \
M_IO_DATA_ASSERT_EN | M_RX_FIFO_RD_ERR_EN | \
M_RX_FIFO_WR_ERR_EN | M_TX_FIFO_RD_ERR_EN | \
M_TX_FIFO_WR_ERR_EN)
/* GENI_S_IRQ_EN fields */
#define S_CMD_DONE_EN BIT(0)
#define S_CMD_OVERRUN_EN BIT(1)
#define S_ILLEGAL_CMD_EN BIT(2)
#define S_CMD_FAILURE_EN BIT(3)
#define S_CMD_CANCEL_EN BIT(4)
#define S_CMD_ABORT_EN BIT(5)
#define S_GP_SYNC_IRQ_0_EN BIT(8)
#define S_GP_IRQ_0_EN BIT(9)
#define S_GP_IRQ_1_EN BIT(10)
#define S_GP_IRQ_2_EN BIT(11)
#define S_GP_IRQ_3_EN BIT(12)
#define S_GP_IRQ_4_EN BIT(13)
#define S_GP_IRQ_5_EN BIT(14)
#define S_IO_DATA_DEASSERT_EN BIT(22)
#define S_IO_DATA_ASSERT_EN BIT(23)
#define S_RX_FIFO_RD_ERR_EN BIT(24)
#define S_RX_FIFO_WR_ERR_EN BIT(25)
#define S_RX_FIFO_WATERMARK_EN BIT(26)
#define S_RX_FIFO_LAST_EN BIT(27)
#define S_COMMON_GENI_S_IRQ_EN (GENMASK(5, 1) | GENMASK(13, 9) | \
S_RX_FIFO_RD_ERR_EN | S_RX_FIFO_WR_ERR_EN)
/* GENI_/TX/RX/RX_RFR/_WATERMARK_REG fields */
#define WATERMARK_MSK GENMASK(5, 0)
/* GENI_TX_FIFO_STATUS fields */
#define TX_FIFO_WC GENMASK(27, 0)
/* GENI_RX_FIFO_STATUS fields */
#define RX_LAST BIT(31)
#define RX_LAST_BYTE_VALID_MSK GENMASK(30, 28)
#define RX_LAST_BYTE_VALID_SHFT 28
#define RX_FIFO_WC_MSK GENMASK(24, 0)
/* SE_GENI_IOS fields */
#define IO2_DATA_IN BIT(1)
#define RX_DATA_IN BIT(0)
/* SE_DMA_TX_IRQ_STAT Register fields */
#define TX_DMA_DONE BIT(0)
#define TX_EOT BIT(1)
#define TX_SBE BIT(2)
#define TX_RESET_DONE BIT(3)
/* SE_DMA_RX_IRQ_STAT Register fields */
#define RX_DMA_DONE BIT(0)
#define RX_EOT BIT(1)
#define RX_SBE BIT(2)
#define RX_RESET_DONE BIT(3)
#define RX_FLUSH_DONE BIT(4)
#define RX_DMA_PARITY_ERR BIT(5)
#define RX_DMA_BREAK GENMASK(8, 7)
#define RX_GENI_GP_IRQ GENMASK(10, 5)
#define RX_GENI_CANCEL_IRQ BIT(11)
#define RX_GENI_GP_IRQ_EXT GENMASK(13, 12)
/* SE_HW_PARAM_0 fields */
#define TX_FIFO_WIDTH_MSK GENMASK(29, 24)
#define TX_FIFO_WIDTH_SHFT 24
/*
* For QUP HW Version >= 3.10 Tx fifo depth support is increased
* to 256bytes and corresponding bits are 16 to 23
*/
#define TX_FIFO_DEPTH_MSK_256_BYTES GENMASK(23, 16)
#define TX_FIFO_DEPTH_MSK GENMASK(21, 16)
#define TX_FIFO_DEPTH_SHFT 16
/* SE_HW_PARAM_1 fields */
#define RX_FIFO_WIDTH_MSK GENMASK(29, 24)
#define RX_FIFO_WIDTH_SHFT 24
/*
* For QUP HW Version >= 3.10 Rx fifo depth support is increased
* to 256bytes and corresponding bits are 16 to 23
*/
#define RX_FIFO_DEPTH_MSK_256_BYTES GENMASK(23, 16)
#define RX_FIFO_DEPTH_MSK GENMASK(21, 16)
#define RX_FIFO_DEPTH_SHFT 16
#define HW_VER_MAJOR_MASK GENMASK(31, 28)
#define HW_VER_MAJOR_SHFT 28
#define HW_VER_MINOR_MASK GENMASK(27, 16)
#define HW_VER_MINOR_SHFT 16
#define HW_VER_STEP_MASK GENMASK(15, 0)
#define GENI_SE_VERSION_MAJOR(ver) ((ver & HW_VER_MAJOR_MASK) >> HW_VER_MAJOR_SHFT)
#define GENI_SE_VERSION_MINOR(ver) ((ver & HW_VER_MINOR_MASK) >> HW_VER_MINOR_SHFT)
#define GENI_SE_VERSION_STEP(ver) (ver & HW_VER_STEP_MASK)
/* QUP SE VERSION value for major number 2 and minor number 5 */
#define QUP_SE_VERSION_2_5 0x20050000
#endif