summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPadmanabhan Komanduru <pkomandu@codeaurora.org>2016-02-18 17:33:58 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:20:57 -0700
commit87f34e2e551b28400eb6f337bc485bd9b34700e6 (patch)
tree788fc0caec9e8cf0abe23f57512c26693c2531e7
parent560e95724ff0e47c2520e207a120b7cc9b947e40 (diff)
clk: msm: mdss: update the procedure for storing DSI PLL codes
In the current implementation, the DSI PLL codes are copied from a CMA memory which has a no-map attribute. Update the logic by reading the pre-calibrated DSI PLL codes from physical memory which is re-mapped to virtual memory allocated in kernel using ioremap_page_range. Once the DSI PLL codes are stored, free the reserved CMA memory back to kernel. Change-Id: Iaa0bbd600dd1a18497cd4dfd7830a9bf88ab0ead Signed-off-by: Padmanabhan Komanduru <pkomandu@codeaurora.org>
-rw-r--r--drivers/clk/msm/mdss/mdss-pll-util.c65
1 files changed, 52 insertions, 13 deletions
diff --git a/drivers/clk/msm/mdss/mdss-pll-util.c b/drivers/clk/msm/mdss/mdss-pll-util.c
index 8be6a29210ec..3f1ccb38abc8 100644
--- a/drivers/clk/msm/mdss/mdss-pll-util.c
+++ b/drivers/clk/msm/mdss/mdss-pll-util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,8 @@
#include <linux/clk/msm-clock-generic.h>
#include <linux/of_address.h>
#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+#include <linux/memblock.h>
#include "mdss-pll.h"
@@ -329,12 +331,26 @@ clk_err:
return rc;
}
+static void mdss_pll_free_bootmem(u32 mem_addr, u32 size)
+{
+ unsigned long pfn_start, pfn_end, pfn_idx;
+
+ pfn_start = mem_addr >> PAGE_SHIFT;
+ pfn_end = (mem_addr + size) >> PAGE_SHIFT;
+ for (pfn_idx = pfn_start; pfn_idx < pfn_end; pfn_idx++)
+ free_reserved_page(pfn_to_page(pfn_idx));
+}
+
static int mdss_pll_util_parse_dt_dfps(struct platform_device *pdev,
struct mdss_pll_resources *pll_res)
{
int rc = 0;
struct device_node *pnode;
- void __iomem *addr;
+ const u32 *addr;
+ struct vm_struct *area;
+ u64 size;
+ u32 offsets[2];
+ unsigned long virt_add;
pnode = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
if (IS_ERR_OR_NULL(pnode)) {
@@ -342,13 +358,29 @@ static int mdss_pll_util_parse_dt_dfps(struct platform_device *pdev,
goto pnode_err;
}
- /* get the physical address for pll codes */
- addr = of_iomap(pnode, 0);
- if (IS_ERR_OR_NULL(addr)) {
- rc = PTR_ERR(addr);
- pr_err("couldn't get dfps physical address\n");
- goto pnode_err;
- }
+ addr = of_get_address(pnode, 0, &size, NULL);
+ if (!addr) {
+ pr_err("failed to parse the dfps memory address\n");
+ rc = -EINVAL;
+ goto pnode_err;
+ }
+ /* maintain compatibility for 32/64 bit */
+ offsets[0] = (u32) of_read_ulong(addr, 2);
+ offsets[1] = (u32) size;
+
+ area = get_vm_area(offsets[1], VM_IOREMAP);
+ if (!area) {
+ rc = -ENOMEM;
+ goto dfps_mem_err;
+ }
+
+ virt_add = (unsigned long)area->addr;
+ rc = ioremap_page_range(virt_add, (virt_add + offsets[1]),
+ offsets[0], PAGE_KERNEL);
+ if (rc) {
+ rc = -ENOMEM;
+ goto ioremap_err;
+ }
pll_res->dfps = kzalloc(sizeof(struct dfps_info), GFP_KERNEL);
if (IS_ERR_OR_NULL(pll_res->dfps)) {
@@ -357,12 +389,19 @@ static int mdss_pll_util_parse_dt_dfps(struct platform_device *pdev,
goto addr_err;
}
- /* memcopy complete dfps structure from physical memory */
- memcpy_fromio(pll_res->dfps, addr, sizeof(struct dfps_info));
+ /* memcopy complete dfps structure from kernel virtual memory */
+ memcpy_fromio(pll_res->dfps, area->addr, sizeof(struct dfps_info));
addr_err:
- iounmap(addr);
-
+ if (virt_add)
+ unmap_kernel_range(virt_add, (unsigned long) size);
+ioremap_err:
+ if (area)
+ vfree(area->addr);
+dfps_mem_err:
+ /* free the dfps memory here */
+ memblock_free(offsets[0], offsets[1]);
+ mdss_pll_free_bootmem(offsets[0], offsets[1]);
pnode_err:
if (pnode)
of_node_put(pnode);