aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTero Kristo2018-08-31 10:01:23 -0500
committerSuman Anna2019-03-02 20:56:36 -0600
commit5c9d2f922f2a263c9339367be0c7239eea3235b7 (patch)
tree067c1f09d257f350483136ca5897e8b7d0fb9001
parentf99e6b3679066f4b1fa9874de12cf27071bc6825 (diff)
downloadiommu-5c9d2f922f2a263c9339367be0c7239eea3235b7.tar.gz
iommu-5c9d2f922f2a263c9339367be0c7239eea3235b7.tar.xz
iommu-5c9d2f922f2a263c9339367be0c7239eea3235b7.zip
ARM: OMAP2+: hwmod_core: improve the support for clkctrl clocks
[ Upstream commit 1b9c30fe01df01c17c5ddd9b4ea02b2ca186d5e7 ] This patch adds support for split memory ranges for clkctrl providers. This is necessary to support the coming clockdomain based split of clkctrl provider ranges, instead of the current CM instance based one. Signed-off-by: Tero Kristo <t-kristo@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> [s-anna@ti.com: cherry-pick commit '1b9c30fe01df' from v4.20] Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c72
1 files changed, 43 insertions, 29 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index cd65ea4e9c54..327cc70e4f18 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -188,16 +188,16 @@
188 188
189/** 189/**
190 * struct clkctrl_provider - clkctrl provider mapping data 190 * struct clkctrl_provider - clkctrl provider mapping data
191 * @addr: base address for the provider 191 * @num_addrs: number of base address ranges for the provider
192 * @size: size of the provider address space 192 * @addr: base address(es) for the provider
193 * @offset: offset of the provider from PRCM instance base 193 * @size: size(s) of the provider address space(s)
194 * @node: device node associated with the provider 194 * @node: device node associated with the provider
195 * @link: list link 195 * @link: list link
196 */ 196 */
197struct clkctrl_provider { 197struct clkctrl_provider {
198 u32 addr; 198 int num_addrs;
199 u32 size; 199 u32 *addr;
200 u16 offset; 200 u32 *size;
201 struct device_node *node; 201 struct device_node *node;
202 struct list_head link; 202 struct list_head link;
203}; 203};
@@ -724,23 +724,34 @@ static int __init _setup_clkctrl_provider(struct device_node *np)
724 const __be32 *addrp; 724 const __be32 *addrp;
725 struct clkctrl_provider *provider; 725 struct clkctrl_provider *provider;
726 u64 size; 726 u64 size;
727 int i;
727 728
728 provider = memblock_virt_alloc(sizeof(*provider), 0); 729 provider = memblock_virt_alloc(sizeof(*provider), 0);
729 if (!provider) 730 if (!provider)
730 return -ENOMEM; 731 return -ENOMEM;
731 732
732 addrp = of_get_address(np, 0, &size, NULL);
733 provider->addr = (u32)of_translate_address(np, addrp);
734 addrp = of_get_address(np->parent, 0, NULL, NULL);
735 provider->offset = provider->addr -
736 (u32)of_translate_address(np->parent, addrp);
737 provider->addr &= ~0xff;
738 provider->size = size | 0xff;
739 provider->node = np; 733 provider->node = np;
740 734
741 pr_debug("%s: %s: %x...%x [+%x]\n", __func__, np->parent->name, 735 provider->num_addrs =
742 provider->addr, provider->addr + provider->size, 736 of_property_count_elems_of_size(np, "reg", sizeof(u32)) / 2;
743 provider->offset); 737
738 provider->addr =
739 memblock_virt_alloc(sizeof(void *) * provider->num_addrs, 0);
740 if (!provider->addr)
741 return -ENOMEM;
742
743 provider->size =
744 memblock_virt_alloc(sizeof(u32) * provider->num_addrs, 0);
745 if (!provider->size)
746 return -ENOMEM;
747
748 for (i = 0; i < provider->num_addrs; i++) {
749 addrp = of_get_address(np, i, &size, NULL);
750 provider->addr[i] = (u32)of_translate_address(np, addrp);
751 provider->size[i] = size;
752 pr_debug("%s: %pOF: %x...%x\n", __func__, np, provider->addr[i],
753 provider->addr[i] + provider->size[i]);
754 }
744 755
745 list_add(&provider->link, &clkctrl_providers); 756 list_add(&provider->link, &clkctrl_providers);
746 757
@@ -787,23 +798,26 @@ static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh)
787 pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr); 798 pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr);
788 799
789 list_for_each_entry(provider, &clkctrl_providers, link) { 800 list_for_each_entry(provider, &clkctrl_providers, link) {
790 if (provider->addr <= addr && 801 int i;
791 provider->addr + provider->size >= addr) {
792 struct of_phandle_args clkspec;
793 802
794 clkspec.np = provider->node; 803 for (i = 0; i < provider->num_addrs; i++) {
795 clkspec.args_count = 2; 804 if (provider->addr[i] <= addr &&
796 clkspec.args[0] = addr - provider->addr - 805 provider->addr[i] + provider->size[i] > addr) {
797 provider->offset; 806 struct of_phandle_args clkspec;
798 clkspec.args[1] = 0;
799 807
800 clk = of_clk_get_from_provider(&clkspec); 808 clkspec.np = provider->node;
809 clkspec.args_count = 2;
810 clkspec.args[0] = addr - provider->addr[0];
811 clkspec.args[1] = 0;
801 812
802 pr_debug("%s: %s got %p (offset=%x, provider=%s)\n", 813 clk = of_clk_get_from_provider(&clkspec);
803 __func__, oh->name, clk, clkspec.args[0],
804 provider->node->parent->name);
805 814
806 return clk; 815 pr_debug("%s: %s got %p (offset=%x, provider=%pOF)\n",
816 __func__, oh->name, clk,
817 clkspec.args[0], provider->node);
818
819 return clk;
820 }
807 } 821 }
808 } 822 }
809 823