Commit 1b9c30fe authored by Tero Kristo's avatar Tero Kristo Committed by Tony Lindgren
Browse files

ARM: OMAP2+: hwmod_core: improve the support for clkctrl clocks



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: default avatarTero Kristo <t-kristo@ti.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 359c533f
Loading
Loading
Loading
Loading
+43 −29
Original line number Original line Diff line number Diff line
@@ -188,16 +188,16 @@


/**
/**
 * struct clkctrl_provider - clkctrl provider mapping data
 * struct clkctrl_provider - clkctrl provider mapping data
 * @addr: base address for the provider
 * @num_addrs: number of base address ranges for the provider
 * @size: size of the provider address space
 * @addr: base address(es) for the provider
 * @offset: offset of the provider from PRCM instance base
 * @size: size(s) of the provider address space(s)
 * @node: device node associated with the provider
 * @node: device node associated with the provider
 * @link: list link
 * @link: list link
 */
 */
struct clkctrl_provider {
struct clkctrl_provider {
	u32			addr;
	int			num_addrs;
	u32			size;
	u32			*addr;
	u16			offset;
	u32			*size;
	struct device_node	*node;
	struct device_node	*node;
	struct list_head	link;
	struct list_head	link;
};
};
@@ -724,23 +724,34 @@ static int __init _setup_clkctrl_provider(struct device_node *np)
	const __be32 *addrp;
	const __be32 *addrp;
	struct clkctrl_provider *provider;
	struct clkctrl_provider *provider;
	u64 size;
	u64 size;
	int i;


	provider = memblock_virt_alloc(sizeof(*provider), 0);
	provider = memblock_virt_alloc(sizeof(*provider), 0);
	if (!provider)
	if (!provider)
		return -ENOMEM;
		return -ENOMEM;


	addrp = of_get_address(np, 0, &size, NULL);
	provider->addr = (u32)of_translate_address(np, addrp);
	addrp = of_get_address(np->parent, 0, NULL, NULL);
	provider->offset = provider->addr -
			   (u32)of_translate_address(np->parent, addrp);
	provider->addr &= ~0xff;
	provider->size = size | 0xff;
	provider->node = np;
	provider->node = np;


	pr_debug("%s: %s: %x...%x [+%x]\n", __func__, np->parent->name,
	provider->num_addrs =
		 provider->addr, provider->addr + provider->size,
		of_property_count_elems_of_size(np, "reg", sizeof(u32)) / 2;
		 provider->offset);

	provider->addr =
		memblock_virt_alloc(sizeof(void *) * provider->num_addrs, 0);
	if (!provider->addr)
		return -ENOMEM;

	provider->size =
		memblock_virt_alloc(sizeof(u32) * provider->num_addrs, 0);
	if (!provider->size)
		return -ENOMEM;

	for (i = 0; i < provider->num_addrs; i++) {
		addrp = of_get_address(np, i, &size, NULL);
		provider->addr[i] = (u32)of_translate_address(np, addrp);
		provider->size[i] = size;
		pr_debug("%s: %pOF: %x...%x\n", __func__, np, provider->addr[i],
			 provider->addr[i] + provider->size[i]);
	}


	list_add(&provider->link, &clkctrl_providers);
	list_add(&provider->link, &clkctrl_providers);


@@ -787,25 +798,28 @@ static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh)
	pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr);
	pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr);


	list_for_each_entry(provider, &clkctrl_providers, link) {
	list_for_each_entry(provider, &clkctrl_providers, link) {
		if (provider->addr <= addr &&
		int i;
		    provider->addr + provider->size >= addr) {

		for (i = 0; i < provider->num_addrs; i++) {
			if (provider->addr[i] <= addr &&
			    provider->addr[i] + provider->size[i] > addr) {
				struct of_phandle_args clkspec;
				struct of_phandle_args clkspec;


				clkspec.np = provider->node;
				clkspec.np = provider->node;
				clkspec.args_count = 2;
				clkspec.args_count = 2;
			clkspec.args[0] = addr - provider->addr -
				clkspec.args[0] = addr - provider->addr[0];
					  provider->offset;
				clkspec.args[1] = 0;
				clkspec.args[1] = 0;


				clk = of_clk_get_from_provider(&clkspec);
				clk = of_clk_get_from_provider(&clkspec);


			pr_debug("%s: %s got %p (offset=%x, provider=%s)\n",
				pr_debug("%s: %s got %p (offset=%x, provider=%pOF)\n",
				 __func__, oh->name, clk, clkspec.args[0],
					 __func__, oh->name, clk,
				 provider->node->parent->name);
					 clkspec.args[0], provider->node);


				return clk;
				return clk;
			}
			}
		}
		}
	}


	return NULL;
	return NULL;
}
}