^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2013-2016, Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/reset-controller.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/devfreq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "ufshcd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "ufshcd-pltfrm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "unipro.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "ufs-qcom.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "ufshci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "ufs_quirks.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define UFS_QCOM_DEFAULT_DBG_PRINT_EN \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) (UFS_QCOM_DBG_PRINT_REGS_EN | UFS_QCOM_DBG_PRINT_TEST_BUS_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) TSTBUS_UAWM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) TSTBUS_UARM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) TSTBUS_TXUC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) TSTBUS_RXUC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) TSTBUS_DFC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) TSTBUS_TRLUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) TSTBUS_TMRLUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) TSTBUS_OCSC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) TSTBUS_UTP_HCI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) TSTBUS_COMBINED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) TSTBUS_WRAPPER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) TSTBUS_UNIPRO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) TSTBUS_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static struct ufs_qcom_host *ufs_qcom_hosts[MAX_UFS_QCOM_HOSTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u32 clk_cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static struct ufs_qcom_host *rcdev_to_ufs_host(struct reset_controller_dev *rcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return container_of(rcd, struct ufs_qcom_host, rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static void ufs_qcom_dump_regs_wrapper(struct ufs_hba *hba, int offset, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) const char *prefix, void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ufshcd_dump_regs(hba, offset, len * 4, prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static int ufs_qcom_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) err = ufshcd_dme_get(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), tx_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) dev_err(hba->dev, "%s: couldn't read PA_CONNECTEDTXDATALANES %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static int ufs_qcom_host_clk_get(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) const char *name, struct clk **clk_out, bool optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) clk = devm_clk_get(dev, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (!IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *clk_out = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) err = PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (optional && err == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *clk_out = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (err != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) dev_err(dev, "failed to get %s err %d\n", name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static int ufs_qcom_host_clk_enable(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) const char *name, struct clk *clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) err = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) dev_err(dev, "%s: %s enable failed %d\n", __func__, name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void ufs_qcom_disable_lane_clks(struct ufs_qcom_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!host->is_lane_clks_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) clk_disable_unprepare(host->tx_l1_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) clk_disable_unprepare(host->tx_l0_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) clk_disable_unprepare(host->rx_l1_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) clk_disable_unprepare(host->rx_l0_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) host->is_lane_clks_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int ufs_qcom_enable_lane_clks(struct ufs_qcom_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct device *dev = host->hba->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (host->is_lane_clks_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) err = ufs_qcom_host_clk_enable(dev, "rx_lane0_sync_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) host->rx_l0_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) err = ufs_qcom_host_clk_enable(dev, "tx_lane0_sync_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) host->tx_l0_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) goto disable_rx_l0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) err = ufs_qcom_host_clk_enable(dev, "rx_lane1_sync_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) host->rx_l1_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) goto disable_tx_l0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) err = ufs_qcom_host_clk_enable(dev, "tx_lane1_sync_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) host->tx_l1_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) goto disable_rx_l1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) host->is_lane_clks_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) disable_rx_l1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) clk_disable_unprepare(host->rx_l1_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) disable_tx_l0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) clk_disable_unprepare(host->tx_l0_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) disable_rx_l0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) clk_disable_unprepare(host->rx_l0_sync_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct device *dev = host->hba->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (has_acpi_companion(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) err = ufs_qcom_host_clk_get(dev, "rx_lane0_sync_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) &host->rx_l0_sync_clk, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) err = ufs_qcom_host_clk_get(dev, "tx_lane0_sync_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) &host->tx_l0_sync_clk, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* In case of single lane per direction, don't read lane1 clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (host->hba->lanes_per_direction > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) err = ufs_qcom_host_clk_get(dev, "rx_lane1_sync_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) &host->rx_l1_sync_clk, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) err = ufs_qcom_host_clk_get(dev, "tx_lane1_sync_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) &host->tx_l1_sync_clk, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int ufs_qcom_link_startup_post_change(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u32 tx_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return ufs_qcom_get_connected_tx_lanes(hba, &tx_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int ufs_qcom_check_hibern8(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u32 tx_fsm_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned long timeout = jiffies + msecs_to_jiffies(HBRN8_POLL_TOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) err = ufshcd_dme_get(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) UIC_ARG_MPHY_TX_GEN_SEL_INDEX(0)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) &tx_fsm_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (err || tx_fsm_val == TX_FSM_HIBERN8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* sleep for max. 200us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) usleep_range(100, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) } while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * we might have scheduled out for long during polling so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * check the state again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (time_after(jiffies, timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) err = ufshcd_dme_get(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) UIC_ARG_MPHY_TX_GEN_SEL_INDEX(0)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) &tx_fsm_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dev_err(hba->dev, "%s: unable to get TX_FSM_STATE, err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) } else if (tx_fsm_val != TX_FSM_HIBERN8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) err = tx_fsm_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) dev_err(hba->dev, "%s: invalid TX_FSM_STATE = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static void ufs_qcom_select_unipro_mode(struct ufs_qcom_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ufshcd_rmwl(host->hba, QUNIPRO_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ufs_qcom_cap_qunipro(host) ? QUNIPRO_SEL : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) REG_UFS_CFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* make sure above configuration is applied before we return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * ufs_qcom_host_reset - reset host controller and PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int ufs_qcom_host_reset(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) bool reenable_intr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (!host->core_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dev_warn(hba->dev, "%s: reset control not set\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) reenable_intr = hba->is_irq_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) disable_irq(hba->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) hba->is_irq_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = reset_control_assert(host->core_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) dev_err(hba->dev, "%s: core_reset assert failed, err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * The hardware requirement for delay between assert/deassert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * is at least 3-4 sleep clock (32.7KHz) cycles, which comes to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * ~125us (4/32768). To be on the safe side add 200us delay.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) usleep_range(200, 210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ret = reset_control_deassert(host->core_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) dev_err(hba->dev, "%s: core_reset deassert failed, err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) usleep_range(1000, 1100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (reenable_intr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) enable_irq(hba->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) hba->is_irq_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct phy *phy = host->generic_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) bool is_rate_B = (UFS_QCOM_LIMIT_HS_RATE == PA_HS_MODE_B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ? true : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* Reset UFS Host Controller and PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ret = ufs_qcom_host_reset(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) dev_warn(hba->dev, "%s: host reset returned %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (is_rate_B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) phy_set_mode(phy, PHY_MODE_UFS_HS_B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* phy initialization - calibrate the phy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ret = phy_init(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dev_err(hba->dev, "%s: phy init failed, ret = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* power on phy - start serdes and phy's power and clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ret = phy_power_on(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) dev_err(hba->dev, "%s: phy power on failed, ret = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) goto out_disable_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ufs_qcom_select_unipro_mode(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) out_disable_phy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) phy_exit(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * The UTP controller has a number of internal clock gating cells (CGCs).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * Internal hardware sub-modules within the UTP controller control the CGCs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * Hardware CGCs disable the clock to inactivate UTP sub-modules not involved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * in a specific operation, UTP controller CGCs are by default disabled and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * this function enables them (after every UFS link startup) to save some power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * leakage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static void ufs_qcom_enable_hw_clk_gating(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ufshcd_writel(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ufshcd_readl(hba, REG_UFS_CFG2) | REG_UFS_CFG2_CGC_EN_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) REG_UFS_CFG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* Ensure that HW clock gating is enabled before next operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static int ufs_qcom_hce_enable_notify(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) enum ufs_notify_change_status status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) case PRE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ufs_qcom_power_up_sequence(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * The PHY PLL output is the source of tx/rx lane symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * clocks, hence, enable the lane clocks only after PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * is initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) err = ufs_qcom_enable_lane_clks(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) case POST_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* check if UFS PHY moved from DISABLED to HIBERN8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) err = ufs_qcom_check_hibern8(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ufs_qcom_enable_hw_clk_gating(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) ufs_qcom_ice_enable(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dev_err(hba->dev, "%s: invalid status %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * Returns zero for success and non-zero in case of a failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static int ufs_qcom_cfg_timers(struct ufs_hba *hba, u32 gear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) u32 hs, u32 rate, bool update_link_startup_timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct ufs_clk_info *clki;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) u32 core_clk_period_in_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) u32 tx_clk_cycles_per_us = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) unsigned long core_clk_rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) u32 core_clk_cycles_per_us = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static u32 pwm_fr_table[][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {UFS_PWM_G1, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {UFS_PWM_G2, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {UFS_PWM_G3, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {UFS_PWM_G4, 0x1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static u32 hs_fr_table_rA[][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {UFS_HS_G1, 0x1F},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {UFS_HS_G2, 0x3e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {UFS_HS_G3, 0x7D},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static u32 hs_fr_table_rB[][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {UFS_HS_G1, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {UFS_HS_G2, 0x49},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {UFS_HS_G3, 0x92},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * The Qunipro controller does not use following registers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * SYS1CLK_1US_REG, TX_SYMBOL_CLK_1US_REG, CLK_NS_REG &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * UFS_REG_PA_LINK_STARTUP_TIMER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * But UTP controller uses SYS1CLK_1US_REG register for Interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * Aggregation logic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (ufs_qcom_cap_qunipro(host) && !ufshcd_is_intr_aggr_allowed(hba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (gear == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) dev_err(hba->dev, "%s: invalid gear = %d\n", __func__, gear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) list_for_each_entry(clki, &hba->clk_list_head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (!strcmp(clki->name, "core_clk"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) core_clk_rate = clk_get_rate(clki->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* If frequency is smaller than 1MHz, set to 1MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (core_clk_rate < DEFAULT_CLK_RATE_HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) core_clk_rate = DEFAULT_CLK_RATE_HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) core_clk_cycles_per_us = core_clk_rate / USEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (ufshcd_readl(hba, REG_UFS_SYS1CLK_1US) != core_clk_cycles_per_us) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ufshcd_writel(hba, core_clk_cycles_per_us, REG_UFS_SYS1CLK_1US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * make sure above write gets applied before we return from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (ufs_qcom_cap_qunipro(host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) core_clk_period_in_ns = NSEC_PER_SEC / core_clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) core_clk_period_in_ns <<= OFFSET_CLK_NS_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) core_clk_period_in_ns &= MASK_CLK_NS_REG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) switch (hs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case FASTAUTO_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) case FAST_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (rate == PA_HS_MODE_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (gear > ARRAY_SIZE(hs_fr_table_rA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) dev_err(hba->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) "%s: index %d exceeds table size %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) __func__, gear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ARRAY_SIZE(hs_fr_table_rA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) tx_clk_cycles_per_us = hs_fr_table_rA[gear-1][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) } else if (rate == PA_HS_MODE_B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (gear > ARRAY_SIZE(hs_fr_table_rB)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) dev_err(hba->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) "%s: index %d exceeds table size %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) __func__, gear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ARRAY_SIZE(hs_fr_table_rB));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) tx_clk_cycles_per_us = hs_fr_table_rB[gear-1][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dev_err(hba->dev, "%s: invalid rate = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) __func__, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) case SLOWAUTO_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) case SLOW_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (gear > ARRAY_SIZE(pwm_fr_table)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) dev_err(hba->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) "%s: index %d exceeds table size %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) __func__, gear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ARRAY_SIZE(pwm_fr_table));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) tx_clk_cycles_per_us = pwm_fr_table[gear-1][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) case UNCHANGED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) dev_err(hba->dev, "%s: invalid mode = %d\n", __func__, hs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (ufshcd_readl(hba, REG_UFS_TX_SYMBOL_CLK_NS_US) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) (core_clk_period_in_ns | tx_clk_cycles_per_us)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* this register 2 fields shall be written at once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ufshcd_writel(hba, core_clk_period_in_ns | tx_clk_cycles_per_us,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) REG_UFS_TX_SYMBOL_CLK_NS_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * make sure above write gets applied before we return from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (update_link_startup_timer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ufshcd_writel(hba, ((core_clk_rate / MSEC_PER_SEC) * 100),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) REG_UFS_PA_LINK_STARTUP_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * make sure that this configuration is applied before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * we return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) out_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static int ufs_qcom_link_startup_notify(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) enum ufs_notify_change_status status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case PRE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (ufs_qcom_cfg_timers(hba, UFS_PWM_G1, SLOWAUTO_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 0, true)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (ufs_qcom_cap_qunipro(host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * set unipro core clock cycles to 150 & clear clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * divider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) err = ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * Some UFS devices (and may be host) have issues if LCC is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * enabled. So we are setting PA_Local_TX_LCC_Enable to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * before link startup which will make sure that both host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * and device TX LCC are disabled once link startup is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (ufshcd_get_local_unipro_ver(hba) != UFS_UNIPRO_VER_1_41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) err = ufshcd_disable_host_tx_lcc(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) case POST_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) ufs_qcom_link_startup_post_change(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static void ufs_qcom_device_reset_ctrl(struct ufs_hba *hba, bool asserted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* reset gpio is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (!host->device_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) gpiod_set_value_cansleep(host->device_reset, asserted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct phy *phy = host->generic_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (ufs_qcom_is_link_off(hba)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * Disable the tx/rx lane symbol clocks before PHY is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * powered down as the PLL source should be disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * after downstream clocks are disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ufs_qcom_disable_lane_clks(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) phy_power_off(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /* reset the connected UFS device during power down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ufs_qcom_device_reset_ctrl(hba, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) } else if (!ufs_qcom_is_link_active(hba)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) ufs_qcom_disable_lane_clks(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct phy *phy = host->generic_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (ufs_qcom_is_link_off(hba)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) err = phy_power_on(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) dev_err(hba->dev, "%s: failed PHY power on: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) err = ufs_qcom_enable_lane_clks(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) } else if (!ufs_qcom_is_link_active(hba)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) err = ufs_qcom_enable_lane_clks(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) err = ufs_qcom_ice_resume(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) hba->is_sys_suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_qcom_host *host, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (host->dev_ref_clk_ctrl_mmio &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) (enable ^ host->is_dev_ref_clk_enabled)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) u32 temp = readl_relaxed(host->dev_ref_clk_ctrl_mmio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) temp |= host->dev_ref_clk_en_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) temp &= ~host->dev_ref_clk_en_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * If we are here to disable this clock it might be immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * after entering into hibern8 in which case we need to make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * sure that device ref_clk is active for specific time after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * hibern8 enter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (!enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) unsigned long gating_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) gating_wait = host->hba->dev_info.clk_gating_wait_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (!gating_wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * bRefClkGatingWaitTime defines the minimum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * time for which the reference clock is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * required by device during transition from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * HS-MODE to LS-MODE or HIBERN8 state. Give it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * more delay to be on the safe side.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) gating_wait += 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) usleep_range(gating_wait, gating_wait + 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) writel_relaxed(temp, host->dev_ref_clk_ctrl_mmio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* ensure that ref_clk is enabled/disabled before we return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * If we call hibern8 exit after this, we need to make sure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * device ref_clk is stable for at least 1us before the hibern8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * exit command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) host->is_dev_ref_clk_enabled = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) enum ufs_notify_change_status status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct ufs_pa_layer_attr *dev_max_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct ufs_pa_layer_attr *dev_req_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct ufs_dev_params ufs_qcom_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (!dev_req_params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) pr_err("%s: incoming dev_req_params is NULL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) case PRE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ufs_qcom_cap.tx_lanes = UFS_QCOM_LIMIT_NUM_LANES_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ufs_qcom_cap.rx_lanes = UFS_QCOM_LIMIT_NUM_LANES_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ufs_qcom_cap.hs_rx_gear = UFS_QCOM_LIMIT_HSGEAR_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) ufs_qcom_cap.hs_tx_gear = UFS_QCOM_LIMIT_HSGEAR_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) ufs_qcom_cap.pwm_rx_gear = UFS_QCOM_LIMIT_PWMGEAR_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ufs_qcom_cap.pwm_tx_gear = UFS_QCOM_LIMIT_PWMGEAR_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) ufs_qcom_cap.rx_pwr_pwm = UFS_QCOM_LIMIT_RX_PWR_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ufs_qcom_cap.tx_pwr_pwm = UFS_QCOM_LIMIT_TX_PWR_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ufs_qcom_cap.rx_pwr_hs = UFS_QCOM_LIMIT_RX_PWR_HS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ufs_qcom_cap.tx_pwr_hs = UFS_QCOM_LIMIT_TX_PWR_HS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) ufs_qcom_cap.hs_rate = UFS_QCOM_LIMIT_HS_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ufs_qcom_cap.desired_working_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) UFS_QCOM_LIMIT_DESIRED_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (host->hw_ver.major == 0x1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * HS-G3 operations may not reliably work on legacy QCOM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * UFS host controller hardware even though capability
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * exchange during link startup phase may end up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * negotiating maximum supported gear as G3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * Hence downgrade the maximum supported gear to HS-G2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (ufs_qcom_cap.hs_tx_gear > UFS_HS_G2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) ufs_qcom_cap.hs_tx_gear = UFS_HS_G2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (ufs_qcom_cap.hs_rx_gear > UFS_HS_G2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ufs_qcom_cap.hs_rx_gear = UFS_HS_G2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) ret = ufshcd_get_pwr_dev_param(&ufs_qcom_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dev_max_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) dev_req_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) pr_err("%s: failed to determine capabilities\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* enable the device ref clock before changing to HS mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (!ufshcd_is_hs_mode(&hba->pwr_info) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ufshcd_is_hs_mode(dev_req_params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) ufs_qcom_dev_ref_clk_ctrl(host, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (host->hw_ver.major >= 0x4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (dev_req_params->gear_tx == UFS_HS_G4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* INITIAL ADAPT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) UIC_ARG_MIB(PA_TXHSADAPTTYPE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) PA_INITIAL_ADAPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /* NO ADAPT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) UIC_ARG_MIB(PA_TXHSADAPTTYPE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) PA_NO_ADAPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) case POST_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) dev_req_params->pwr_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) dev_req_params->hs_rate, false)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dev_err(hba->dev, "%s: ufs_qcom_cfg_timers() failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * we return error code at the end of the routine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * but continue to configure UFS_PHY_TX_LANE_ENABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * and bus voting as usual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* cache the power mode parameters to use internally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) memcpy(&host->dev_req_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) dev_req_params, sizeof(*dev_req_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /* disable the device ref clock if entered PWM mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (ufshcd_is_hs_mode(&hba->pwr_info) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) !ufshcd_is_hs_mode(dev_req_params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) ufs_qcom_dev_ref_clk_ctrl(host, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static int ufs_qcom_quirk_host_pa_saveconfigtime(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) u32 pa_vs_config_reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) err = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_VS_CONFIG_REG1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) &pa_vs_config_reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* Allow extension of MSB bits of PA_SaveConfigTime attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) err = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_VS_CONFIG_REG1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) (pa_vs_config_reg1 | (1 << 12)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_SAVECONFIGTIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) err = ufs_qcom_quirk_host_pa_saveconfigtime(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (hba->dev_info.wmanufacturerid == UFS_VENDOR_WDC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) hba->dev_quirks |= UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (host->hw_ver.major == 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return ufshci_version(1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return ufshci_version(2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * ufs_qcom_advertise_quirks - advertise the known QCOM UFS controller quirks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * @hba: host controller instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * QCOM UFS host controller might have some non standard behaviours (quirks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * than what is specified by UFSHCI specification. Advertise all such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * quirks to standard UFS host controller driver so standard takes them into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * account.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (host->hw_ver.major == 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) hba->quirks |= UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) | UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) | UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (host->hw_ver.minor == 0x0001 && host->hw_ver.step == 0x0001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) hba->quirks |= UFSHCD_QUIRK_BROKEN_INTR_AGGR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) hba->quirks |= UFSHCD_QUIRK_BROKEN_LCC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (host->hw_ver.major == 0x2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) hba->quirks |= UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (!ufs_qcom_cap_qunipro(host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* Legacy UniPro mode still need following quirks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) hba->quirks |= (UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) | UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) | UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) static void ufs_qcom_set_caps(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) hba->caps |= UFSHCD_CAP_CLK_SCALING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) hba->caps |= UFSHCD_CAP_WB_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) hba->caps |= UFSHCD_CAP_CRYPTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (host->hw_ver.major >= 0x2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) host->caps = UFS_QCOM_CAP_QUNIPRO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) UFS_QCOM_CAP_RETAIN_SEC_CFG_AFTER_PWR_COLLAPSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * ufs_qcom_setup_clocks - enables/disable clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * @hba: host controller instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * @on: If true, enable clocks else disable them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * @status: PRE_CHANGE or POST_CHANGE notify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * Returns 0 on success, non-zero on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) enum ufs_notify_change_status status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * In case ufs_qcom_init() is not yet done, simply ignore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * This ufs_qcom_setup_clocks() shall be called from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * ufs_qcom_init() after init is done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) case PRE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (!on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (!ufs_qcom_is_link_active(hba)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /* disable device ref_clk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) ufs_qcom_dev_ref_clk_ctrl(host, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) case POST_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /* enable the device ref clock for HS mode*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (ufshcd_is_hs_mode(&hba->pwr_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ufs_qcom_dev_ref_clk_ctrl(host, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) ufs_qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct ufs_qcom_host *host = rcdev_to_ufs_host(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) /* Currently this code only knows about a single reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) WARN_ON(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) ufs_qcom_assert_reset(host->hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /* provide 1ms delay to let the reset pulse propagate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) usleep_range(1000, 1100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ufs_qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct ufs_qcom_host *host = rcdev_to_ufs_host(rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) /* Currently this code only knows about a single reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) WARN_ON(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ufs_qcom_deassert_reset(host->hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * after reset deassertion, phy will need all ref clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * voltage, current to settle down before starting serdes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) usleep_range(1000, 1100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static const struct reset_control_ops ufs_qcom_reset_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .assert = ufs_qcom_reset_assert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .deassert = ufs_qcom_reset_deassert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) #define ANDROID_BOOT_DEV_MAX 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) static char android_boot_dev[ANDROID_BOOT_DEV_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) static int __init get_android_boot_dev(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) strlcpy(android_boot_dev, str, ANDROID_BOOT_DEV_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) __setup("androidboot.bootdevice=", get_android_boot_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * ufs_qcom_init - bind phy with controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * @hba: host controller instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * Binds PHY with controller and powers up PHY enabling clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * and regulators.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * Returns -EPROBE_DEFER if binding fails, returns negative error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * on phy power up failure and returns zero on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static int ufs_qcom_init(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct device *dev = hba->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct platform_device *pdev = to_platform_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct ufs_qcom_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (strlen(android_boot_dev) && strcmp(android_boot_dev, dev_name(dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (!host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) dev_err(dev, "%s: no memory for qcom ufs host\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* Make a two way bind between the qcom host and the hba */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) host->hba = hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) ufshcd_set_variant(hba, host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* Setup the reset control of HCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) host->core_reset = devm_reset_control_get(hba->dev, "rst");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (IS_ERR(host->core_reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) err = PTR_ERR(host->core_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) dev_warn(dev, "Failed to get reset control %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) host->core_reset = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) /* Fire up the reset controller. Failure here is non-fatal. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) host->rcdev.of_node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) host->rcdev.ops = &ufs_qcom_reset_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) host->rcdev.owner = dev->driver->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) host->rcdev.nr_resets = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) err = devm_reset_controller_register(dev, &host->rcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) dev_warn(dev, "Failed to register reset controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * voting/devoting device ref_clk source is time consuming hence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * skip devoting it during aggressive clock gating. This clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * will still be gated off during runtime suspend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) host->generic_phy = devm_phy_get(dev, "ufsphy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (host->generic_phy == ERR_PTR(-EPROBE_DEFER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * UFS driver might be probed before the phy driver does.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * In that case we would like to return EPROBE_DEFER code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) err = -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) dev_warn(dev, "%s: required phy device. hasn't probed yet. err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) goto out_variant_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) } else if (IS_ERR(host->generic_phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (has_acpi_companion(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) host->generic_phy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) err = PTR_ERR(host->generic_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) dev_err(dev, "%s: PHY get failed %d\n", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) goto out_variant_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) host->device_reset = devm_gpiod_get_optional(dev, "reset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (IS_ERR(host->device_reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) err = PTR_ERR(host->device_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (err != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) dev_err(dev, "failed to acquire reset gpio: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) goto out_variant_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) ufs_qcom_get_controller_revision(hba, &host->hw_ver.major,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) &host->hw_ver.minor, &host->hw_ver.step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) * for newer controllers, device reference clock control bit has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * moved inside UFS controller register address space itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (host->hw_ver.major >= 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) host->dev_ref_clk_ctrl_mmio = hba->mmio_base + REG_UFS_CFG1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) host->dev_ref_clk_en_mask = BIT(26);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /* "dev_ref_clk_ctrl_mem" is optional resource */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) "dev_ref_clk_ctrl_mem");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) host->dev_ref_clk_ctrl_mmio =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (IS_ERR(host->dev_ref_clk_ctrl_mmio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) "%s: could not map dev_ref_clk_ctrl_mmio, err %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) PTR_ERR(host->dev_ref_clk_ctrl_mmio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) host->dev_ref_clk_ctrl_mmio = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) host->dev_ref_clk_en_mask = BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) err = ufs_qcom_init_lane_clks(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) goto out_variant_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) ufs_qcom_set_caps(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) ufs_qcom_advertise_quirks(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) err = ufs_qcom_ice_init(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) goto out_variant_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ufs_qcom_setup_clocks(hba, true, POST_CHANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (hba->dev->id < MAX_UFS_QCOM_HOSTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) ufs_qcom_hosts[hba->dev->id] = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) host->dbg_print_en |= UFS_QCOM_DEFAULT_DBG_PRINT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ufs_qcom_get_default_testbus_cfg(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) err = ufs_qcom_testbus_config(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) dev_warn(dev, "%s: failed to configure the testbus %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) out_variant_clear:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) ufshcd_set_variant(hba, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static void ufs_qcom_exit(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) ufs_qcom_disable_lane_clks(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) phy_power_off(host->generic_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) phy_exit(host->generic_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static int ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) u32 clk_cycles)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) u32 core_clk_ctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (clk_cycles > DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) err = ufshcd_dme_get(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) &core_clk_ctrl_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_MAX_CORE_CLK_1US_CYCLES_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) core_clk_ctrl_reg |= clk_cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) /* Clear CORE_CLK_DIV_EN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) err = ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) core_clk_ctrl_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) static int ufs_qcom_clk_scale_up_pre_change(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) /* nothing to do as of now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static int ufs_qcom_clk_scale_up_post_change(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (!ufs_qcom_cap_qunipro(host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* set unipro core clock cycles to 150 and clear clock divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) static int ufs_qcom_clk_scale_down_pre_change(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) u32 core_clk_ctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (!ufs_qcom_cap_qunipro(host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) err = ufshcd_dme_get(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) &core_clk_ctrl_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) /* make sure CORE_CLK_DIV_EN is cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (!err &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) (core_clk_ctrl_reg & DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) core_clk_ctrl_reg &= ~DME_VS_CORE_CLK_CTRL_CORE_CLK_DIV_EN_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) err = ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) UIC_ARG_MIB(DME_VS_CORE_CLK_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) core_clk_ctrl_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) static int ufs_qcom_clk_scale_down_post_change(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (!ufs_qcom_cap_qunipro(host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) /* set unipro core clock cycles to 75 and clear clock divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) return ufs_qcom_set_dme_vs_core_clk_ctrl_clear_div(hba, 75);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) bool scale_up, enum ufs_notify_change_status status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) struct ufs_pa_layer_attr *dev_req_params = &host->dev_req_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (status == PRE_CHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) err = ufshcd_uic_hibern8_enter(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (scale_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) err = ufs_qcom_clk_scale_up_pre_change(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) err = ufs_qcom_clk_scale_down_pre_change(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) ufshcd_uic_hibern8_exit(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if (scale_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) err = ufs_qcom_clk_scale_up_post_change(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) err = ufs_qcom_clk_scale_down_post_change(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (err || !dev_req_params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) ufshcd_uic_hibern8_exit(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ufs_qcom_cfg_timers(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) dev_req_params->gear_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) dev_req_params->pwr_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) dev_req_params->hs_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) ufshcd_uic_hibern8_exit(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) static void ufs_qcom_print_hw_debug_reg_all(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) void *priv, void (*print_fn)(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) int offset, int num_regs, const char *str, void *priv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) struct ufs_qcom_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (unlikely(!hba)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) pr_err("%s: hba is NULL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (unlikely(!print_fn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) dev_err(hba->dev, "%s: print_fn is NULL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) if (!(host->dbg_print_en & UFS_QCOM_DBG_PRINT_REGS_EN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) reg = ufs_qcom_get_debug_reg_offset(host, UFS_UFS_DBG_RD_REG_OCSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) print_fn(hba, reg, 44, "UFS_UFS_DBG_RD_REG_OCSC ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) reg = ufshcd_readl(hba, REG_UFS_CFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) reg |= UTP_DBG_RAMS_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) ufshcd_writel(hba, reg, REG_UFS_CFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) reg = ufs_qcom_get_debug_reg_offset(host, UFS_UFS_DBG_RD_EDTL_RAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) print_fn(hba, reg, 32, "UFS_UFS_DBG_RD_EDTL_RAM ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) reg = ufs_qcom_get_debug_reg_offset(host, UFS_UFS_DBG_RD_DESC_RAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) print_fn(hba, reg, 128, "UFS_UFS_DBG_RD_DESC_RAM ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) reg = ufs_qcom_get_debug_reg_offset(host, UFS_UFS_DBG_RD_PRDT_RAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) print_fn(hba, reg, 64, "UFS_UFS_DBG_RD_PRDT_RAM ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) /* clear bit 17 - UTP_DBG_RAMS_EN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) ufshcd_rmwl(hba, UTP_DBG_RAMS_EN, 0, REG_UFS_CFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) reg = ufs_qcom_get_debug_reg_offset(host, UFS_DBG_RD_REG_UAWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) print_fn(hba, reg, 4, "UFS_DBG_RD_REG_UAWM ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) reg = ufs_qcom_get_debug_reg_offset(host, UFS_DBG_RD_REG_UARM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) print_fn(hba, reg, 4, "UFS_DBG_RD_REG_UARM ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) reg = ufs_qcom_get_debug_reg_offset(host, UFS_DBG_RD_REG_TXUC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) print_fn(hba, reg, 48, "UFS_DBG_RD_REG_TXUC ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) reg = ufs_qcom_get_debug_reg_offset(host, UFS_DBG_RD_REG_RXUC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) print_fn(hba, reg, 27, "UFS_DBG_RD_REG_RXUC ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) reg = ufs_qcom_get_debug_reg_offset(host, UFS_DBG_RD_REG_DFC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) print_fn(hba, reg, 19, "UFS_DBG_RD_REG_DFC ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) reg = ufs_qcom_get_debug_reg_offset(host, UFS_DBG_RD_REG_TRLUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) print_fn(hba, reg, 34, "UFS_DBG_RD_REG_TRLUT ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) reg = ufs_qcom_get_debug_reg_offset(host, UFS_DBG_RD_REG_TMRLUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) print_fn(hba, reg, 9, "UFS_DBG_RD_REG_TMRLUT ", priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static void ufs_qcom_enable_test_bus(struct ufs_qcom_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (host->dbg_print_en & UFS_QCOM_DBG_PRINT_TEST_BUS_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) ufshcd_rmwl(host->hba, UFS_REG_TEST_BUS_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) UFS_REG_TEST_BUS_EN, REG_UFS_CFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ufshcd_rmwl(host->hba, TEST_BUS_EN, TEST_BUS_EN, REG_UFS_CFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) ufshcd_rmwl(host->hba, UFS_REG_TEST_BUS_EN, 0, REG_UFS_CFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) ufshcd_rmwl(host->hba, TEST_BUS_EN, 0, REG_UFS_CFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) /* provide a legal default configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) host->testbus.select_major = TSTBUS_UNIPRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) host->testbus.select_minor = 37;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static bool ufs_qcom_testbus_cfg_is_ok(struct ufs_qcom_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (host->testbus.select_major >= TSTBUS_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) dev_err(host->hba->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) "%s: UFS_CFG1[TEST_BUS_SEL} may not equal 0x%05X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) __func__, host->testbus.select_major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) int ufs_qcom_testbus_config(struct ufs_qcom_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) u32 mask = TEST_BUS_SUB_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (!ufs_qcom_testbus_cfg_is_ok(host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) switch (host->testbus.select_major) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) case TSTBUS_UAWM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) reg = UFS_TEST_BUS_CTRL_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) offset = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) case TSTBUS_UARM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) reg = UFS_TEST_BUS_CTRL_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) offset = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) case TSTBUS_TXUC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) reg = UFS_TEST_BUS_CTRL_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) case TSTBUS_RXUC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) reg = UFS_TEST_BUS_CTRL_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) case TSTBUS_DFC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) reg = UFS_TEST_BUS_CTRL_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) offset = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) case TSTBUS_TRLUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) reg = UFS_TEST_BUS_CTRL_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) offset = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) case TSTBUS_TMRLUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) reg = UFS_TEST_BUS_CTRL_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) case TSTBUS_OCSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) reg = UFS_TEST_BUS_CTRL_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) case TSTBUS_WRAPPER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) reg = UFS_TEST_BUS_CTRL_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) offset = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) case TSTBUS_COMBINED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) reg = UFS_TEST_BUS_CTRL_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) offset = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) case TSTBUS_UTP_HCI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) reg = UFS_TEST_BUS_CTRL_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) case TSTBUS_UNIPRO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) reg = UFS_UNIPRO_CFG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) offset = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) mask = 0xFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) * No need for a default case, since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) * ufs_qcom_testbus_cfg_is_ok() checks that the configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) * is legal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) mask <<= offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) ufshcd_rmwl(host->hba, TEST_BUS_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) (u32)host->testbus.select_major << 19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) REG_UFS_CFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) ufshcd_rmwl(host->hba, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) (u32)host->testbus.select_minor << offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) ufs_qcom_enable_test_bus(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) * Make sure the test bus configuration is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) * committed before returning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) ufshcd_dump_regs(hba, REG_UFS_SYS1CLK_1US, 16 * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) "HCI Vendor Specific Registers ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) ufs_qcom_print_hw_debug_reg_all(hba, NULL, ufs_qcom_dump_regs_wrapper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * ufs_qcom_device_reset() - toggle the (optional) device reset line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) * @hba: per-adapter instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * Toggles the (optional) reset line to reset the attached device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) static int ufs_qcom_device_reset(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) struct ufs_qcom_host *host = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) /* reset gpio is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (!host->device_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * The UFS device shall detect reset pulses of 1us, sleep for 10us to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) * be on the safe side.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) ufs_qcom_device_reset_ctrl(hba, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) usleep_range(10, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) ufs_qcom_device_reset_ctrl(hba, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) usleep_range(10, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) #if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) static void ufs_qcom_config_scaling_param(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) struct devfreq_dev_profile *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) static struct devfreq_simple_ondemand_data *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) d = (struct devfreq_simple_ondemand_data *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) p->polling_ms = 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) d->upthreshold = 70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) d->downdifferential = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) static void ufs_qcom_config_scaling_param(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) struct devfreq_dev_profile *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) * struct ufs_hba_qcom_vops - UFS QCOM specific variant operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) * The variant operations configure the necessary controller and PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * handshake during initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) static const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) .name = "qcom",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) .init = ufs_qcom_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) .exit = ufs_qcom_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) .get_ufs_hci_version = ufs_qcom_get_ufs_hci_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) .clk_scale_notify = ufs_qcom_clk_scale_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) .setup_clocks = ufs_qcom_setup_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) .hce_enable_notify = ufs_qcom_hce_enable_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) .link_startup_notify = ufs_qcom_link_startup_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) .pwr_change_notify = ufs_qcom_pwr_change_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) .apply_dev_quirks = ufs_qcom_apply_dev_quirks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) .suspend = ufs_qcom_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) .resume = ufs_qcom_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) .dbg_register_dump = ufs_qcom_dump_dbg_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) .device_reset = ufs_qcom_device_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) .config_scaling_param = ufs_qcom_config_scaling_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) .program_key = ufs_qcom_ice_program_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) * ufs_qcom_probe - probe routine of the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) * @pdev: pointer to Platform device handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) * Return zero for success and non-zero for failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) static int ufs_qcom_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) /* Perform generic probe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) err = ufshcd_pltfrm_init(pdev, &ufs_hba_qcom_vops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) * ufs_qcom_remove - set driver_data of the device to NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) * @pdev: pointer to platform device handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) * Always returns 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) static int ufs_qcom_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) struct ufs_hba *hba = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) pm_runtime_get_sync(&(pdev)->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) ufshcd_remove(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) static const struct of_device_id ufs_qcom_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) { .compatible = "qcom,ufshc"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) MODULE_DEVICE_TABLE(of, ufs_qcom_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) static const struct acpi_device_id ufs_qcom_acpi_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) { "QCOM24A5" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) MODULE_DEVICE_TABLE(acpi, ufs_qcom_acpi_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) static const struct dev_pm_ops ufs_qcom_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) .suspend = ufshcd_pltfrm_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) .resume = ufshcd_pltfrm_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) .runtime_suspend = ufshcd_pltfrm_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) .runtime_resume = ufshcd_pltfrm_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) .runtime_idle = ufshcd_pltfrm_runtime_idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) static struct platform_driver ufs_qcom_pltform = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) .probe = ufs_qcom_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) .remove = ufs_qcom_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) .shutdown = ufshcd_pltfrm_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) .name = "ufshcd-qcom",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) .pm = &ufs_qcom_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) .of_match_table = of_match_ptr(ufs_qcom_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) .acpi_match_table = ACPI_PTR(ufs_qcom_acpi_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) module_platform_driver(ufs_qcom_pltform);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) MODULE_LICENSE("GPL v2");