diff options
author | Ajay Gupta <ajayg@nvidia.com> | 2013-05-20 14:46:22 -0700 |
---|---|---|
committer | Mandar Padmawar <mpadmawar@nvidia.com> | 2013-05-23 00:51:55 -0700 |
commit | 200f540142475f6fbdd22327efd0f89cecc8ea65 (patch) | |
tree | 52a7f050a868b8d919799ea2fdd23f64e7d4dece /drivers/usb | |
parent | 819ac5b3ac5613f82b8e05e04fd8d45d95ec18bc (diff) |
usb: xhci: tegra: process set bandwidth fw message
Bug 1266234
Change-Id: I0c89373913391bd8b04f2245d178eae44a9bded5
Signed-off-by: Ajay Gupta <ajayg@nvidia.com>
Reviewed-on: http://git-master/r/231004
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Ashutosh Jha <ajha@nvidia.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/xhci-tegra.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 8dd7a03e8bfd..3044af00befe 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -32,6 +32,7 @@ #include <mach/clk.h> #include <mach/tegra_usb_pad_ctrl.h> #include <mach/tegra_usb_pmc.h> +#include <mach/mc.h> #include "xhci-tegra.h" #include "xhci.h" @@ -532,10 +533,17 @@ static int tegra_xusb_partitions_clk_init(struct tegra_xhci_hcd *tegra) struct platform_device *pdev = tegra->pdev; int err = 0; + tegra->emc_clk = devm_clk_get(&pdev->dev, "emc"); + if (IS_ERR(tegra->emc_clk)) { + dev_err(&pdev->dev, "Failed to get xusb.emc clock\n"); + return PTR_ERR(tegra->emc_clk); + } + tegra->pll_re_vco_clk = devm_clk_get(&pdev->dev, "pll_re_vco"); if (IS_ERR(tegra->pll_re_vco_clk)) { dev_err(&pdev->dev, "Failed to get refPLLE clock\n"); - return PTR_ERR(tegra->pll_re_vco_clk); + err = PTR_ERR(tegra->pll_re_vco_clk); + goto get_emc_clk_failed; } /* get the clock handle of 120MHz clock source */ @@ -596,8 +604,17 @@ static int tegra_xusb_partitions_clk_init(struct tegra_xhci_hcd *tegra) goto eanble_ss_clk_failed; } + err = clk_enable(tegra->emc_clk); + if (err) { + dev_err(&pdev->dev, "Failed to enable xusb.emc clk\n"); + goto eanble_emc_clk_failed; + } + return 0; +eanble_emc_clk_failed: + clk_disable(tegra->ss_clk); + eanble_ss_clk_failed: clk_disable(tegra->host_clk); @@ -622,6 +639,9 @@ clk_get_clk_m_failed: get_pll_u_480M_failed: tegra->pll_re_vco_clk = NULL; +get_emc_clk_failed: + tegra->emc_clk = NULL; + return err; } @@ -1548,6 +1568,7 @@ static int tegra_xhci_host_elpg_entry(struct tegra_xhci_hcd *tegra) tegra->host_pwr_gated = true; clk_disable(tegra->pll_re_vco_clk); + clk_disable(tegra->emc_clk); /* set port ownership to SNPS */ tegra_xhci_release_port_ownership(tegra, true); @@ -1784,6 +1805,7 @@ tegra_xhci_host_partition_elpg_exit(struct tegra_xhci_hcd *tegra) if (!tegra->hc_in_elpg) return 0; + clk_enable(tegra->emc_clk); clk_enable(tegra->pll_re_vco_clk); /* Step 2: Enable clock to host partition */ clk_enable(tegra->host_clk); @@ -1933,6 +1955,8 @@ tegra_xhci_process_mbox_message(struct work_struct *work) struct tegra_xhci_hcd *tegra = container_of(work, struct tegra_xhci_hcd, mbox_work); struct xhci_hcd *xhci = tegra->xhci; + unsigned int freq_khz; + bool send_ack_to_fw = true; mutex_lock(&tegra->mbox_lock); @@ -1981,17 +2005,14 @@ tegra_xhci_process_mbox_message(struct work_struct *work) __func__); goto send_sw_response; case MBOX_CMD_SET_BW: - /* make sure mem bandwidth - * is requested in MB/s - */ - ret = tegra_xusb_request_clk_rate( - tegra, - tegra->emc_clk, - tegra->cmd_data, - &sw_resp); - if (ret) - xhci_err(xhci, "%s: could not set required mem bw.\n", - __func__); + /* fw sends BW request in MByte/sec */ + freq_khz = tegra_emc_bw_to_freq_req(tegra->cmd_data << 10); + clk_set_rate(tegra->emc_clk, freq_khz * 1000); + + /* clear mbox owner as ACK will not be sent for this request */ + writel(0, tegra->fpci_base + XUSB_CFG_ARU_MBOX_OWNER); + send_ack_to_fw = false; + goto send_sw_response; case MBOX_CMD_SAVE_DFE_CTLE_CTX: tegra_xhci_save_dfe_ctle_context(tegra); @@ -2014,11 +2035,12 @@ tegra_xhci_process_mbox_message(struct work_struct *work) return; send_sw_response: - writel(sw_resp, tegra->fpci_base + XUSB_CFG_ARU_MBOX_DATA_IN); - - cmd = readl(tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD); - cmd |= MBOX_INT_EN | MBOX_FALC_INT_EN; - writel(cmd, tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD); + if (send_ack_to_fw) { + writel(sw_resp, tegra->fpci_base + XUSB_CFG_ARU_MBOX_DATA_IN); + cmd = readl(tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD); + cmd |= MBOX_INT_EN | MBOX_FALC_INT_EN; + writel(cmd, tegra->fpci_base + XUSB_CFG_ARU_MBOX_CMD); + } mutex_unlock(&tegra->mbox_lock); } |