#include <mach/clk.h>
#include <mach/tegra_bb.h>
+#include <mach/tegra_bbc_proxy.h>
#include <linux/platform_data/nvshm.h>
#include "clock.h"
struct workqueue_struct *workqueue;
struct work_struct work;
struct clk *emc_clk;
+ struct device *proxy_dev;
};
static unsigned long emc_min_freq;
clk_set_rate(bb->emc_clk, emc_min_freq);
pr_debug("bbc setting floor to %lu\n", emc_min_freq/1000000);
+ /* restore iso bw request*/
+ tegra_bbc_proxy_restore_iso(bb->proxy_dev);
+
/* reenable pmc_wake_det irq */
tegra_bb_enable_pmc_wake();
irq_set_irq_type(INT_PMC_WAKE_INT, IRQF_TRIGGER_HIGH);
bb->prev_state = bb->state;
spin_unlock_irqrestore(&bb->lock, flags);
+ /* remove iso bandwitdh request from bbc */
+ tegra_bbc_proxy_clear_iso(bb->proxy_dev);
+
/* going from high to 0 */
if (emc_flags & EMC_DSR)
tegra_emc_dsr_override(TEGRA_EMC_DSR_NORMAL);
tegra_bb_set_emc_floor(BBC_MC_MIN_FREQ, 0);
+ /* get bbc proxy device struct, it should be registered
+ * before this driver.
+ */
+ bb->proxy_dev = bus_find_device_by_name(&platform_bus_type, NULL,
+ "tegra_bbc_proxy");
+ if (!bb->proxy_dev)
+ dev_warn(&pdev->dev, "%s: bbc proxy device not found!\n",
+ __func__);
+
ret = request_irq(bb->mem_req_soon, tegra_bb_mem_req_soon,
IRQF_TRIGGER_RISING, "bb_mem_req_soon", bb);
if (ret) {
unsigned int i_thresh_lte_adjperiod; /* lte i_thresh adj period */
unsigned int threshold; /* current edp threshold value */
unsigned int state; /* current edp state value */
+ /* last iso settings with proxy driver */
+ unsigned int last_bw;
+ unsigned int last_ult;
struct work_struct edp_work;
struct mutex edp_lock; /* lock for edp operations */
if (!ret)
dev_err(dev, "can't reserve iso bw\n");
+ bbc->last_bw = bw;
+ bbc->last_ult = ult;
+
tegra_set_latency_allowance(TEGRA_LA_BBCR, bw / 1000);
tegra_set_latency_allowance(TEGRA_LA_BBCW, bw / 1000);
struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
mutex_lock(&bbc->iso_lock);
+ bbc->last_bw = bw;
+ bbc->last_ult = lt;
+
ret = bbc_bw_request_unlocked(dev, mode, bw, lt, margin);
mutex_unlock(&bbc->iso_lock);
}
EXPORT_SYMBOL(tegra_bbc_proxy_bw_request);
+int tegra_bbc_proxy_restore_iso(struct device *dev)
+{
+ int ret;
+ struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
+
+ if (!bbc)
+ return -EINVAL;
+
+ mutex_lock(&bbc->iso_lock);
+ ret = bbc_bw_request_unlocked(dev, 0, bbc->last_bw,
+ bbc->last_ult, bbc->margin);
+ mutex_unlock(&bbc->iso_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_bbc_proxy_restore_iso);
+
+int tegra_bbc_proxy_clear_iso(struct device *dev)
+{
+ int ret;
+ struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
+
+ if (!bbc)
+ return -EINVAL;
+
+ mutex_lock(&bbc->iso_lock);
+ ret = bbc_bw_request_unlocked(dev, 0, 0,
+ 1000, bbc->margin);
+ mutex_unlock(&bbc->iso_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_bbc_proxy_clear_iso);
+
static ssize_t iso_res_realize_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
}
mutex_lock(&bbc->iso_lock);
+ bbc->last_bw = bw;
+ bbc->last_ult = ult;
+
ret = bbc_bw_request_unlocked(dev, 0, bw, ult, bbc->margin);
mutex_unlock(&bbc->iso_lock);