msm8960: slim: Program slimbus slew rate register
If applicable, make sure that slimbus doesn't violate slew rate spec
by programming the slimbus slew rate register
CRs-Fixed: 307733
Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 5eeca31..cc1264d 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1720,6 +1720,7 @@
#define LPASS_SLIMBUS_PHYS 0x28080000
#define LPASS_SLIMBUS_BAM_PHYS 0x28084000
+#define LPASS_SLIMBUS_SLEW (MSM8960_TLMM_PHYS + 0x207C)
/* Board info for the slimbus slave device */
static struct resource slimbus_res[] = {
{
@@ -1735,6 +1736,12 @@
.name = "slimbus_bam_physical",
},
{
+ .start = LPASS_SLIMBUS_SLEW,
+ .end = LPASS_SLIMBUS_SLEW + 4 - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "slimbus_slew_reg",
+ },
+ {
.start = SLIMBUS0_CORE_EE1_IRQ,
.end = SLIMBUS0_CORE_EE1_IRQ,
.flags = IORESOURCE_IRQ,
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 3678b30..1e4302b 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -204,6 +204,7 @@
struct slim_framer framer;
struct device *dev;
void __iomem *base;
+ struct resource *slew_mem;
u32 curr_bw;
u8 msg_cnt;
u32 tx_buf[10];
@@ -1463,6 +1464,40 @@
sps_deregister_bam_device(dev->bam.hdl);
}
+static void msm_slim_prg_slew(struct platform_device *pdev,
+ struct msm_slim_ctrl *dev)
+{
+ struct resource *slew_io;
+ void __iomem *slew_reg;
+ /* SLEW RATE register for this slimbus */
+ dev->slew_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "slimbus_slew_reg");
+ if (!dev->slew_mem) {
+ dev_dbg(&pdev->dev, "no slimbus slew resource\n");
+ return;
+ }
+ slew_io = request_mem_region(dev->slew_mem->start,
+ resource_size(dev->slew_mem), pdev->name);
+ if (!slew_io) {
+ dev_dbg(&pdev->dev, "slimbus-slew mem claimed\n");
+ dev->slew_mem = NULL;
+ return;
+ }
+
+ slew_reg = ioremap(dev->slew_mem->start, resource_size(dev->slew_mem));
+ if (!slew_reg) {
+ dev_dbg(dev->dev, "slew register mapping failed");
+ release_mem_region(dev->slew_mem->start,
+ resource_size(dev->slew_mem));
+ dev->slew_mem = NULL;
+ return;
+ }
+ writel_relaxed(1, slew_reg);
+ /* Make sure slimbus-slew rate enabling goes through */
+ wmb();
+ iounmap(slew_reg);
+}
+
static int __devinit msm_slim_probe(struct platform_device *pdev)
{
struct msm_slim_ctrl *dev;
@@ -1562,10 +1597,7 @@
dev->rclk = clk_get(dev->dev, "audio_slimbus_clk");
- if (dev->rclk) {
- clk_set_rate(dev->rclk, SLIM_ROOT_FREQ);
- clk_enable(dev->rclk);
- } else {
+ if (!dev->rclk) {
dev_err(dev->dev, "slimbus clock not found");
goto err_clk_get_failed;
}
@@ -1592,6 +1624,11 @@
ret = -ENOMEM;
goto err_sat_failed;
}
+
+ msm_slim_prg_slew(pdev, dev);
+ clk_set_rate(dev->rclk, SLIM_ROOT_FREQ);
+ clk_enable(dev->rclk);
+
dev->satd->dev = dev;
dev->satd->satcl.name = "msm_sat_dev";
spin_lock_init(&dev->satd->lock);
@@ -1695,6 +1732,7 @@
struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
struct resource *bam_mem;
struct resource *slim_mem;
+ struct resource *slew_mem = dev->slew_mem;
struct msm_slim_sat *sat = dev->satd;
slim_remove_device(&sat->satcl);
kfree(sat->satch);
@@ -1713,6 +1751,8 @@
"slimbus_bam_physical");
if (bam_mem)
release_mem_region(bam_mem->start, resource_size(bam_mem));
+ if (slew_mem)
+ release_mem_region(slew_mem->start, resource_size(slew_mem));
slim_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"slimbus_physical");
if (slim_mem)