/* * bw: memory BW in KBps * lt: latency in usec */ int tegra_camera_isomgr_request(struct tegra_camera *camera, unsigned long bw, unsigned long lt) { int ret = 0; dev_dbg(camera->dev, "%s++ bw=%lu, lt=%lu\n", __func__, bw, lt); /* return value of tegra_isomgr_reserve is dvfs latency in usec */ ret = tegra_isomgr_reserve(camera->isomgr_handle, bw, /* KB/sec */ lt); /* usec */ if (!ret) { dev_err(camera->dev, "%s: failed to reserve %lu KBps\n", __func__, bw); return -ENOMEM; } /* return value of tegra_isomgr_realize is dvfs latency in usec */ ret = tegra_isomgr_realize(camera->isomgr_handle); if (ret) dev_dbg(camera->dev, "%s: camera isomgr latency is %d usec", __func__, ret); else { dev_err(camera->dev, "%s: failed to realize %lu KBps\n", __func__, bw); return -ENOMEM; } return 0; }
int tegra_camera_unregister(struct tegra_camera *camera) { int i; dev_info(camera->dev, "%s: ++\n", __func__); for (i = 0; i < CAMERA_CLK_MAX; i++) clk_put(camera->clock[i].clk); #ifdef CONFIG_ARCH_TEGRA_11x_SOC /* * Return memory bandwidth to isomgr. * If bandwidth is zero, then latency will be ignored * in tegra_isomgr_reserve(). */ { int ret = 0; ret = tegra_isomgr_reserve(camera->isomgr_handle, 0, /* KB/sec */ 0); /* usec */ if (!ret) return -ENOMEM; tegra_isomgr_unregister(camera->isomgr_handle); camera->isomgr_handle = NULL; } #endif kfree(camera); return 0; }
static int bbc_bw_request_unlocked(struct device *dev, u32 mode, u32 bw, u32 lt, u32 margin) { int ret; u32 dvfs_latency; struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev); dev_dbg(dev, "bbc iso request - bw: %u lt: %u margin: %u mode: %u\n", bw, lt, margin, mode); if (bw > MAX_ISO_BW_REQ) return -EINVAL; if (margin > MAX_ISO_BW_REQ) return -EINVAL; if (mode) atomic_set(&bbc->mode, mode); if ((bw != bbc->bw) || (lt != bbc->lt)) { dvfs_latency = tegra_isomgr_reserve(bbc->isomgr_handle, bw, lt); if (!dvfs_latency) { dev_err(dev, "can't reserve iso bw\n"); return -EINVAL; } bbc->bw = bw; dvfs_latency = tegra_isomgr_realize(bbc->isomgr_handle); if (!dvfs_latency) { dev_err(dev, "can't realize iso bw\n"); return -EINVAL; } bbc->lt = lt; } if (margin != bbc->margin) { ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0, margin, true); if (ret) { dev_err(dev, "can't margin for bbc bw\n"); return ret; } bbc->margin = margin; } return 0; }
static int bbc_bw_request_unlocked(struct device *dev, u32 mode, u32 bw, u32 lt, u32 margin) { int ret; struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev); if (bw > MAX_ISO_BW_REQ) return -EINVAL; if (margin > MAX_ISO_BW_REQ) return -EINVAL; if (margin != bbc->margin) { ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0, margin, true); if (ret) { dev_err(dev, "can't margin for bbc bw\n"); return ret; } bbc->margin = margin; } if ((bw != bbc->bw) || (lt != bbc->lt)) { ret = tegra_isomgr_reserve(bbc->isomgr_handle, bw, lt); if (!ret) { dev_err(dev, "can't reserve iso bw\n"); return ret; } bbc->bw = bw; ret = tegra_isomgr_realize(bbc->isomgr_handle); if (!ret) { dev_err(dev, "can't realize iso bw\n"); return ret; } bbc->lt = lt; tegra_set_latency_allowance(TEGRA_LA_BBCR, bw / 1000); tegra_set_latency_allowance(TEGRA_LA_BBCW, bw / 1000); } return 0; }