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>
This commit is contained in:
parent
560e95724f
commit
87f34e2e55
1 changed files with 52 additions and 13 deletions
|
@ -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
|
* 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
|
* 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/clk/msm-clock-generic.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/memblock.h>
|
||||||
|
|
||||||
#include "mdss-pll.h"
|
#include "mdss-pll.h"
|
||||||
|
|
||||||
|
@ -329,12 +331,26 @@ clk_err:
|
||||||
return rc;
|
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,
|
static int mdss_pll_util_parse_dt_dfps(struct platform_device *pdev,
|
||||||
struct mdss_pll_resources *pll_res)
|
struct mdss_pll_resources *pll_res)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct device_node *pnode;
|
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);
|
pnode = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
|
||||||
if (IS_ERR_OR_NULL(pnode)) {
|
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;
|
goto pnode_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the physical address for pll codes */
|
addr = of_get_address(pnode, 0, &size, NULL);
|
||||||
addr = of_iomap(pnode, 0);
|
if (!addr) {
|
||||||
if (IS_ERR_OR_NULL(addr)) {
|
pr_err("failed to parse the dfps memory address\n");
|
||||||
rc = PTR_ERR(addr);
|
rc = -EINVAL;
|
||||||
pr_err("couldn't get dfps physical address\n");
|
goto pnode_err;
|
||||||
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);
|
pll_res->dfps = kzalloc(sizeof(struct dfps_info), GFP_KERNEL);
|
||||||
if (IS_ERR_OR_NULL(pll_res->dfps)) {
|
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;
|
goto addr_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* memcopy complete dfps structure from physical memory */
|
/* memcopy complete dfps structure from kernel virtual memory */
|
||||||
memcpy_fromio(pll_res->dfps, addr, sizeof(struct dfps_info));
|
memcpy_fromio(pll_res->dfps, area->addr, sizeof(struct dfps_info));
|
||||||
|
|
||||||
addr_err:
|
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:
|
pnode_err:
|
||||||
if (pnode)
|
if (pnode)
|
||||||
of_node_put(pnode);
|
of_node_put(pnode);
|
||||||
|
|
Loading…
Add table
Reference in a new issue