From 5e8370f1fa01bf232ca4770c6d81bbf42437d2a3 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 18 Apr 2012 19:10:06 -0600 Subject: ARM: OMAP2+: hwmod: add omap_hwmod_get_resource_byname() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The timer integration code pokes around in hwmod data structures. Those data structures are about to change. Define a function, omap_hwmod_get_resource_byname(), for the timer integration code to use instead. The original patch has been changed to use struct resource by Tony's request, although the caller of this function should not be a driver._ Platform drivers should get their data through the regular platform_* functions; DT drivers through the appropriate of_* functions. This a function is only for use by OMAP core code in arch/arm/*omap*. Signed-off-by: Paul Walmsley Cc: Benoît Cousson Cc: Tony Lindgren --- arch/arm/plat-omap/include/plat/omap_hwmod.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 3f26db4ee8e6..062a31d438cd 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -581,6 +581,8 @@ int omap_hwmod_softreset(struct omap_hwmod *oh); int omap_hwmod_count_resources(struct omap_hwmod *oh); int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); +int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type, + const char *name, struct resource *res); struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh); void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh); -- cgit v1.2.3 From 3d10f0d6d93c153d92c5ea31fccc354ef9716214 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 19 Apr 2012 04:03:55 -0600 Subject: ARM: OMAP4: hwmod data: add OCP_USER_DSP; mark omap44xx_dsp__iva appropriately MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One of the OMAP4 links was missing OCP_USER flags, since it was only used by the DSP initiator, and we did not have an OCP_USER_DSP flag. Future patches will switch the hwmod code and data to register interfaces, rather than hwmods, and it will be mandatory for all interfaces to have at least one user bit set. This patch resolves the issue by adding OCP_USER_DSP and marking the DSP-IVA interface appropriately. Signed-off-by: Paul Walmsley Cc: Benoît Cousson --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 + arch/arm/plat-omap/include/plat/omap_hwmod.h | 1 + 2 files changed, 2 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index a69d38da7cf6..1af2eb118222 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1089,6 +1089,7 @@ static struct omap_hwmod_ocp_if omap44xx_dsp__iva = { .master = &omap44xx_dsp_hwmod, .slave = &omap44xx_iva_hwmod, .clk = "dpll_iva_m5x2_ck", + .user = OCP_USER_DSP, }; /* dsp master ports */ diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 062a31d438cd..92752b8a6fbb 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -213,6 +213,7 @@ struct omap_hwmod_addr_space { */ #define OCP_USER_MPU (1 << 0) #define OCP_USER_SDMA (1 << 1) +#define OCP_USER_DSP (1 << 2) /* omap_hwmod_ocp_if.flags bits */ #define OCPIF_SWSUP_IDLE (1 << 0) -- cgit v1.2.3 From 515237d6fef36ebc476a4ce9204a3234ac14cf45 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 19 Apr 2012 04:03:57 -0600 Subject: ARM: OMAP2+: hwmod: extend OCP_* register offsets from 16 to 32 bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend the OCP_* register offsets in the struct omap_hwmod_class_sysconfig to 32 bits. This is required to add the OMAP4+ GPU hwmod, which uses OCP_* register offsets larger than 16 bits. Another possible solution may be to simply add a single 16 bit offset field in this structure, and to add code to factor that offset into all OCP_* register accesses. This would save some memory, since almost no modules need 32 bit offsets. Signed-off-by: Paul Walmsley Cc: Benoît Cousson --- arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 92752b8a6fbb..65285317f80b 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -328,9 +328,9 @@ struct omap_hwmod_sysc_fields { * then this field has to be populated with the correct offset structure. */ struct omap_hwmod_class_sysconfig { - u16 rev_offs; - u16 sysc_offs; - u16 syss_offs; + u32 rev_offs; + u32 sysc_offs; + u32 syss_offs; u16 sysc_flags; struct omap_hwmod_sysc_fields *sysc_fields; u8 srst_udelay; -- cgit v1.2.3 From 2221b5cddc2ebcfa4b0217266d2edc98e7eec93b Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 19 Apr 2012 04:04:30 -0600 Subject: ARM: OMAP2+: hwmod: add support for link registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for direct IP block interconnect ("link") registration to the hwmod code via a new function, omap_hwmod_register_links(). This will replace direct registration of hwmods, and a subsequent patch will remove omap_hwmod_register(). This change will allow a subsequent patch to remove the hwmod data link arrays. This will reduce the size of the hwmod static data and also make it easier to generate the data files. It will also make it possible to share some of the struct omap_hwmod records across multiple SoCs, since the link array pointers will be removed from the struct omap_hwmod. The downside is that boot time will increase. Minimizing boot time was the reason why the link arrays were originally introduced. Removing them will require extra computation during boot to allocate memory and associate IP blocks with their interconnects. However, since the current kernel development focus is on reducing the number of lines in arch/arm/mach-omap2/, boot time impact is now seemingly considered a lower priority. This patch contains additional complexity to reduce the number of memory allocations required for this change. This reduces the boot time impact: total hwmod link registration time was ~ 2655 microseconds with a simple allocation strategy, but is now ~ 549 microseconds[1] with the approach taken by this patch. 1. Measured on a BeagleBoard 35xx @ 500MHz MPU/333 MHz CORE, average of 7 samples. Total uncertainty is +/- 61 microseconds. Signed-off-by: Paul Walmsley Cc: Benoît Cousson --- arch/arm/mach-omap2/omap_hwmod.c | 297 +++++++++++++++++++++++++-- arch/arm/plat-omap/include/plat/omap_hwmod.h | 24 +++ 2 files changed, 305 insertions(+), 16 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 8cf837d2332a..99b913aa0cb9 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -137,6 +137,7 @@ #include #include #include +#include #include "common.h" #include @@ -159,25 +160,54 @@ /* Name of the OMAP hwmod for the MPU */ #define MPU_INITIATOR_NAME "mpu" +/* + * Number of struct omap_hwmod_link records per struct + * omap_hwmod_ocp_if record (master->slave and slave->master) + */ +#define LINKS_PER_OCP_IF 2 + /* omap_hwmod_list contains all registered struct omap_hwmods */ static LIST_HEAD(omap_hwmod_list); /* mpu_oh: used to add/remove MPU initiator from sleepdep list */ static struct omap_hwmod *mpu_oh; +/* + * link_registration: set to true if hwmod interfaces are being registered + * directly; set to false if hwmods are being registered directly + */ +static bool link_registration; + +/* + * linkspace: ptr to a buffer that struct omap_hwmod_link records are + * allocated from - used to reduce the number of small memory + * allocations, which has a significant impact on performance + */ +static struct omap_hwmod_link *linkspace; + +/* + * free_ls, max_ls: array indexes into linkspace; representing the + * next free struct omap_hwmod_link index, and the maximum number of + * struct omap_hwmod_link records allocated (respectively) + */ +static unsigned short free_ls, max_ls, ls_supp; /* Private functions */ /** - * _fetch_next_ocp_if - return @i'th OCP interface in an array - * @p: ptr to a ptr to the list_head inside the ocp_if to return (not yet used) + * _fetch_next_ocp_if - return next OCP interface in an array or list + * @p: ptr to a ptr to the list_head inside the ocp_if to return * @old: ptr to an array of struct omap_hwmod_ocp_if records * @i: pointer to the index into the @old array * * Return a pointer to the next struct omap_hwmod_ocp_if record in a - * sequence. Currently returns a struct omap_hwmod_ocp_if record - * corresponding to the element index pointed to by @i in the @old - * array, and increments the index pointed to by @i. + * sequence. If hwmods are being registered directly, then return a + * struct omap_hwmod_ocp_if record corresponding to the element index + * pointed to by @i in the + * @old array. Otherwise, return a pointer to the struct + * omap_hwmod_ocp_if record containing the struct list_head record pointed + * to by @p, and set the pointer pointed to by @p to point to the next + * struct list_head record in the list. */ static struct omap_hwmod_ocp_if *_fetch_next_ocp_if(struct list_head **p, struct omap_hwmod_ocp_if **old, @@ -185,7 +215,13 @@ static struct omap_hwmod_ocp_if *_fetch_next_ocp_if(struct list_head **p, { struct omap_hwmod_ocp_if *oi; - oi = old[*i]; + if (!link_registration) { + oi = old[*i]; + } else { + oi = list_entry(*p, struct omap_hwmod_link, node)->ocp_if; + *p = (*p)->next; + } + *i = *i + 1; return oi; @@ -606,12 +642,16 @@ static int _init_main_clk(struct omap_hwmod *oh) static int _init_interface_clks(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; + struct list_head *p = NULL; struct clk *c; int i = 0; int ret = 0; + if (link_registration) + p = oh->slave_ports.next; + while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(NULL, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, oh->slaves, &i); if (!os->clk) continue; @@ -664,6 +704,7 @@ static int _init_opt_clks(struct omap_hwmod *oh) static int _enable_clocks(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; + struct list_head *p = NULL; int i = 0; pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name); @@ -671,8 +712,11 @@ static int _enable_clocks(struct omap_hwmod *oh) if (oh->_clk) clk_enable(oh->_clk); + if (link_registration) + p = oh->slave_ports.next; + while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(NULL, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, oh->slaves, &i); if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) clk_enable(os->_clk); @@ -692,6 +736,7 @@ static int _enable_clocks(struct omap_hwmod *oh) static int _disable_clocks(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; + struct list_head *p = NULL; int i = 0; pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); @@ -699,8 +744,11 @@ static int _disable_clocks(struct omap_hwmod *oh) if (oh->_clk) clk_disable(oh->_clk); + if (link_registration) + p = oh->slave_ports.next; + while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(NULL, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, oh->slaves, &i); if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) clk_disable(os->_clk); @@ -975,8 +1023,12 @@ static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name, { int i, j; struct omap_hwmod_ocp_if *os; + struct list_head *p = NULL; bool found = false; + if (link_registration) + p = oh->slave_ports.next; + i = 0; while (i < oh->slaves_cnt) { os = _fetch_next_ocp_if(NULL, oh->slaves, &i); @@ -1019,6 +1071,7 @@ static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name, static void __init _save_mpu_port_index(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os = NULL; + struct list_head *p = NULL; int i = 0; if (!oh) @@ -1026,9 +1079,13 @@ static void __init _save_mpu_port_index(struct omap_hwmod *oh) oh->_int_flags |= _HWMOD_NO_MPU_PORT; + if (link_registration) + p = oh->slave_ports.next; + while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(NULL, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, oh->slaves, &i); if (os->user & OCP_USER_MPU) { + oh->_mpu_port = os; oh->_mpu_port_index = i - 1; oh->_int_flags &= ~_HWMOD_NO_MPU_PORT; break; @@ -1056,7 +1113,10 @@ static struct omap_hwmod_ocp_if *_find_mpu_rt_port(struct omap_hwmod *oh) if (!oh || oh->_int_flags & _HWMOD_NO_MPU_PORT || oh->slaves_cnt == 0) return NULL; - return oh->slaves[oh->_mpu_port_index]; + if (!link_registration) + return oh->slaves[oh->_mpu_port_index]; + else + return oh->_mpu_port; }; /** @@ -1976,6 +2036,8 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) if (!oh) return; + _save_mpu_port_index(oh); + if (oh->_int_flags & _HWMOD_NO_MPU_PORT) return; @@ -2042,13 +2104,16 @@ static int __init _init(struct omap_hwmod *oh, void *data) static void __init _setup_iclk_autoidle(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; + struct list_head *p = NULL; int i = 0; if (oh->_state != _HWMOD_STATE_INITIALIZED) return; + if (link_registration) + p = oh->slave_ports.next; while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(NULL, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, oh->slaves, &i); if (!os->_clk) continue; @@ -2219,10 +2284,10 @@ static int __init _register(struct omap_hwmod *oh) if (_lookup(oh->name)) return -EEXIST; - _save_mpu_port_index(oh); - list_add_tail(&oh->node, &omap_hwmod_list); + INIT_LIST_HEAD(&oh->master_ports); + INIT_LIST_HEAD(&oh->slave_ports); spin_lock_init(&oh->_lock); oh->_state = _HWMOD_STATE_REGISTERED; @@ -2237,6 +2302,160 @@ static int __init _register(struct omap_hwmod *oh) return 0; } +/** + * _alloc_links - return allocated memory for hwmod links + * @ml: pointer to a struct omap_hwmod_link * for the master link + * @sl: pointer to a struct omap_hwmod_link * for the slave link + * + * Return pointers to two struct omap_hwmod_link records, via the + * addresses pointed to by @ml and @sl. Will first attempt to return + * memory allocated as part of a large initial block, but if that has + * been exhausted, will allocate memory itself. Since ideally this + * second allocation path will never occur, the number of these + * 'supplemental' allocations will be logged when debugging is + * enabled. Returns 0. + */ +static int __init _alloc_links(struct omap_hwmod_link **ml, + struct omap_hwmod_link **sl) +{ + unsigned int sz; + + if ((free_ls + LINKS_PER_OCP_IF) <= max_ls) { + *ml = &linkspace[free_ls++]; + *sl = &linkspace[free_ls++]; + return 0; + } + + sz = sizeof(struct omap_hwmod_link) * LINKS_PER_OCP_IF; + + *sl = NULL; + *ml = alloc_bootmem(sz); + + memset(*ml, 0, sz); + + *sl = (void *)(*ml) + sizeof(struct omap_hwmod_link); + + ls_supp++; + pr_debug("omap_hwmod: supplemental link allocations needed: %d\n", + ls_supp * LINKS_PER_OCP_IF); + + return 0; +}; + +/** + * _add_link - add an interconnect between two IP blocks + * @oi: pointer to a struct omap_hwmod_ocp_if record + * + * Add struct omap_hwmod_link records connecting the master IP block + * specified in @oi->master to @oi, and connecting the slave IP block + * specified in @oi->slave to @oi. This code is assumed to run before + * preemption or SMP has been enabled, thus avoiding the need for + * locking in this code. Changes to this assumption will require + * additional locking. Returns 0. + */ +static int __init _add_link(struct omap_hwmod_ocp_if *oi) +{ + struct omap_hwmod_link *ml, *sl; + + pr_debug("omap_hwmod: %s -> %s: adding link\n", oi->master->name, + oi->slave->name); + + _alloc_links(&ml, &sl); + + ml->ocp_if = oi; + INIT_LIST_HEAD(&ml->node); + list_add(&ml->node, &oi->master->master_ports); + oi->master->masters_cnt++; + + sl->ocp_if = oi; + INIT_LIST_HEAD(&sl->node); + list_add(&sl->node, &oi->slave->slave_ports); + oi->slave->slaves_cnt++; + + return 0; +} + +/** + * _register_link - register a struct omap_hwmod_ocp_if + * @oi: struct omap_hwmod_ocp_if * + * + * Registers the omap_hwmod_ocp_if record @oi. Returns -EEXIST if it + * has already been registered; -EINVAL if @oi is NULL or if the + * record pointed to by @oi is missing required fields; or 0 upon + * success. + * + * XXX The data should be copied into bootmem, so the original data + * should be marked __initdata and freed after init. This would allow + * unneeded omap_hwmods to be freed on multi-OMAP configurations. + */ +static int __init _register_link(struct omap_hwmod_ocp_if *oi) +{ + if (!oi || !oi->master || !oi->slave || !oi->user) + return -EINVAL; + + if (oi->_int_flags & _OCPIF_INT_FLAGS_REGISTERED) + return -EEXIST; + + pr_debug("omap_hwmod: registering link from %s to %s\n", + oi->master->name, oi->slave->name); + + /* + * Register the connected hwmods, if they haven't been + * registered already + */ + if (oi->master->_state != _HWMOD_STATE_REGISTERED) + _register(oi->master); + + if (oi->slave->_state != _HWMOD_STATE_REGISTERED) + _register(oi->slave); + + _add_link(oi); + + oi->_int_flags |= _OCPIF_INT_FLAGS_REGISTERED; + + return 0; +} + +/** + * _alloc_linkspace - allocate large block of hwmod links + * @ois: pointer to an array of struct omap_hwmod_ocp_if records to count + * + * Allocate a large block of struct omap_hwmod_link records. This + * improves boot time significantly by avoiding the need to allocate + * individual records one by one. If the number of records to + * allocate in the block hasn't been manually specified, this function + * will count the number of struct omap_hwmod_ocp_if records in @ois + * and use that to determine the allocation size. For SoC families + * that require multiple list registrations, such as OMAP3xxx, this + * estimation process isn't optimal, so manual estimation is advised + * in those cases. Returns -EEXIST if the allocation has already occurred + * or 0 upon success. + */ +static int __init _alloc_linkspace(struct omap_hwmod_ocp_if **ois) +{ + unsigned int i = 0; + unsigned int sz; + + if (linkspace) { + WARN(1, "linkspace already allocated\n"); + return -EEXIST; + } + + if (max_ls == 0) + while (ois[i++]) + max_ls += LINKS_PER_OCP_IF; + + sz = sizeof(struct omap_hwmod_link) * max_ls; + + pr_debug("omap_hwmod: %s: allocating %d byte linkspace (%d links)\n", + __func__, sz, max_ls); + + linkspace = alloc_bootmem(sz); + + memset(linkspace, 0, sz); + + return 0; +} /* Public functions */ @@ -2376,6 +2595,9 @@ int __init omap_hwmod_register(struct omap_hwmod **ohs) { int r, i; + if (link_registration) + return -EINVAL; + if (!ohs) return 0; @@ -2389,6 +2611,41 @@ int __init omap_hwmod_register(struct omap_hwmod **ohs) return 0; } +/** + * omap_hwmod_register_links - register an array of hwmod links + * @ois: pointer to an array of omap_hwmod_ocp_if to register + * + * Intended to be called early in boot before the clock framework is + * initialized. If @ois is not null, will register all omap_hwmods + * listed in @ois that are valid for this chip. Returns 0. + */ +int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois) +{ + int r, i; + + if (!ois) + return 0; + + link_registration = true; + + if (!linkspace) { + if (_alloc_linkspace(ois)) { + pr_err("omap_hwmod: could not allocate link space\n"); + return -ENOMEM; + } + } + + i = 0; + do { + r = _register_link(ois[i]); + WARN(r && r != -EEXIST, + "omap_hwmod: _register_link(%s -> %s) returned %d\n", + ois[i]->master->name, ois[i]->slave->name, r); + } while (ois[++i]); + + return 0; +} + /** * _ensure_mpu_hwmod_is_setup - ensure the MPU SS hwmod is init'ed and set up * @oh: pointer to the hwmod currently being set up (usually not the MPU) @@ -2631,13 +2888,17 @@ int omap_hwmod_reset(struct omap_hwmod *oh) int omap_hwmod_count_resources(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; + struct list_head *p = NULL; int ret; int i = 0; ret = _count_mpu_irqs(oh) + _count_sdma_reqs(oh); + if (link_registration) + p = oh->slave_ports.next; + while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(NULL, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, oh->slaves, &i); ret += _count_ocp_if_addr_spaces(os); } @@ -2657,6 +2918,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh) int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) { struct omap_hwmod_ocp_if *os; + struct list_head *p = NULL; int i, j, mpu_irqs_cnt, sdma_reqs_cnt, addr_cnt; int r = 0; @@ -2680,9 +2942,12 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) r++; } + if (link_registration) + p = oh->slave_ports.next; + i = 0; while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(NULL, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, oh->slaves, &i); addr_cnt = _count_ocp_if_addr_spaces(os); for (j = 0; j < addr_cnt; j++) { diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 65285317f80b..09679032603c 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -219,6 +219,10 @@ struct omap_hwmod_addr_space { #define OCPIF_SWSUP_IDLE (1 << 0) #define OCPIF_CAN_BURST (1 << 1) +/* omap_hwmod_ocp_if._int_flags possibilities */ +#define _OCPIF_INT_FLAGS_REGISTERED (1 << 0) + + /** * struct omap_hwmod_ocp_if - OCP interface data * @master: struct omap_hwmod that initiates OCP transactions on this link @@ -230,6 +234,7 @@ struct omap_hwmod_addr_space { * @width: OCP data width * @user: initiators using this interface (see OCP_USER_* macros above) * @flags: OCP interface flags (see OCPIF_* macros above) + * @_int_flags: internal flags (see _OCPIF_INT_FLAGS* macros above) * * It may also be useful to add a tag_cnt field for OCP2.x devices. * @@ -248,6 +253,7 @@ struct omap_hwmod_ocp_if { u8 width; u8 user; u8 flags; + u8 _int_flags; }; @@ -476,6 +482,16 @@ struct omap_hwmod_class { int (*reset)(struct omap_hwmod *oh); }; +/** + * struct omap_hwmod_link - internal structure linking hwmods with ocp_ifs + * @ocp_if: OCP interface structure record pointer + * @node: list_head pointing to next struct omap_hwmod_link in a list + */ +struct omap_hwmod_link { + struct omap_hwmod_ocp_if *ocp_if; + struct list_head node; +}; + /** * struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks) * @name: name of the hwmod @@ -494,6 +510,7 @@ struct omap_hwmod_class { * @_sysc_cache: internal-use hwmod flags * @_mpu_rt_va: cached register target start address (internal use) * @_mpu_port_index: cached MPU register target slave ID (internal use) + * @_mpu_port: cached MPU register target slave (internal use) * @opt_clks_cnt: number of @opt_clks * @master_cnt: number of @master entries * @slaves_cnt: number of @slave entries @@ -512,6 +529,8 @@ struct omap_hwmod_class { * * Parameter names beginning with an underscore are managed internally by * the omap_hwmod code and should not be set during initialization. + * + * @masters and @slaves are now deprecated. */ struct omap_hwmod { const char *name; @@ -532,11 +551,14 @@ struct omap_hwmod { struct clockdomain *clkdm; struct omap_hwmod_ocp_if **masters; /* connect to *_IA */ struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */ + struct list_head master_ports; /* connect to *_IA */ + struct list_head slave_ports; /* connect to *_TA */ void *dev_attr; u32 _sysc_cache; void __iomem *_mpu_rt_va; spinlock_t _lock; struct list_head node; + struct omap_hwmod_ocp_if *_mpu_port; u16 flags; u8 _mpu_port_index; u8 response_lat; @@ -622,4 +644,6 @@ extern int omap2430_hwmod_init(void); extern int omap3xxx_hwmod_init(void); extern int omap44xx_hwmod_init(void); +extern int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois); + #endif -- cgit v1.2.3 From 11cd4b94cb491894b8a192635abf159fc1917f4d Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 19 Apr 2012 04:04:32 -0600 Subject: ARM: OMAP: hwmod: remove code support for direct hwmod registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the data has been converted to use interface registration, we can remove the (now unused) direct hwmod registration code. Signed-off-by: Paul Walmsley Cc: Benoît Cousson --- arch/arm/mach-omap2/omap_hwmod.c | 124 +++++++-------------------- arch/arm/plat-omap/include/plat/omap_hwmod.h | 7 -- 2 files changed, 33 insertions(+), 98 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 99b913aa0cb9..bf86f7e8f91f 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -172,12 +172,6 @@ static LIST_HEAD(omap_hwmod_list); /* mpu_oh: used to add/remove MPU initiator from sleepdep list */ static struct omap_hwmod *mpu_oh; -/* - * link_registration: set to true if hwmod interfaces are being registered - * directly; set to false if hwmods are being registered directly - */ -static bool link_registration; - /* * linkspace: ptr to a buffer that struct omap_hwmod_link records are * allocated from - used to reduce the number of small memory @@ -195,32 +189,22 @@ static unsigned short free_ls, max_ls, ls_supp; /* Private functions */ /** - * _fetch_next_ocp_if - return next OCP interface in an array or list + * _fetch_next_ocp_if - return the next OCP interface in a list * @p: ptr to a ptr to the list_head inside the ocp_if to return - * @old: ptr to an array of struct omap_hwmod_ocp_if records - * @i: pointer to the index into the @old array - * - * Return a pointer to the next struct omap_hwmod_ocp_if record in a - * sequence. If hwmods are being registered directly, then return a - * struct omap_hwmod_ocp_if record corresponding to the element index - * pointed to by @i in the - * @old array. Otherwise, return a pointer to the struct - * omap_hwmod_ocp_if record containing the struct list_head record pointed - * to by @p, and set the pointer pointed to by @p to point to the next - * struct list_head record in the list. + * @i: pointer to the index of the element pointed to by @p in the list + * + * Return a pointer to the struct omap_hwmod_ocp_if record + * containing the struct list_head pointed to by @p, and increment + * @p such that a future call to this routine will return the next + * record. */ static struct omap_hwmod_ocp_if *_fetch_next_ocp_if(struct list_head **p, - struct omap_hwmod_ocp_if **old, int *i) { struct omap_hwmod_ocp_if *oi; - if (!link_registration) { - oi = old[*i]; - } else { - oi = list_entry(*p, struct omap_hwmod_link, node)->ocp_if; - *p = (*p)->next; - } + oi = list_entry(*p, struct omap_hwmod_link, node)->ocp_if; + *p = (*p)->next; *i = *i + 1; @@ -642,16 +626,15 @@ static int _init_main_clk(struct omap_hwmod *oh) static int _init_interface_clks(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - struct list_head *p = NULL; + struct list_head *p; struct clk *c; int i = 0; int ret = 0; - if (link_registration) - p = oh->slave_ports.next; + p = oh->slave_ports.next; while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, &i); if (!os->clk) continue; @@ -704,7 +687,7 @@ static int _init_opt_clks(struct omap_hwmod *oh) static int _enable_clocks(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - struct list_head *p = NULL; + struct list_head *p; int i = 0; pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name); @@ -712,11 +695,10 @@ static int _enable_clocks(struct omap_hwmod *oh) if (oh->_clk) clk_enable(oh->_clk); - if (link_registration) - p = oh->slave_ports.next; + p = oh->slave_ports.next; while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, &i); if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) clk_enable(os->_clk); @@ -736,7 +718,7 @@ static int _enable_clocks(struct omap_hwmod *oh) static int _disable_clocks(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - struct list_head *p = NULL; + struct list_head *p; int i = 0; pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); @@ -744,11 +726,10 @@ static int _disable_clocks(struct omap_hwmod *oh) if (oh->_clk) clk_disable(oh->_clk); - if (link_registration) - p = oh->slave_ports.next; + p = oh->slave_ports.next; while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, &i); if (os->_clk && (os->flags & OCPIF_SWSUP_IDLE)) clk_disable(os->_clk); @@ -1026,12 +1007,11 @@ static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name, struct list_head *p = NULL; bool found = false; - if (link_registration) - p = oh->slave_ports.next; + p = oh->slave_ports.next; i = 0; while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(NULL, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, &i); if (!os->addr) return -ENOENT; @@ -1071,7 +1051,7 @@ static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name, static void __init _save_mpu_port_index(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os = NULL; - struct list_head *p = NULL; + struct list_head *p; int i = 0; if (!oh) @@ -1079,14 +1059,12 @@ static void __init _save_mpu_port_index(struct omap_hwmod *oh) oh->_int_flags |= _HWMOD_NO_MPU_PORT; - if (link_registration) - p = oh->slave_ports.next; + p = oh->slave_ports.next; while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, &i); if (os->user & OCP_USER_MPU) { oh->_mpu_port = os; - oh->_mpu_port_index = i - 1; oh->_int_flags &= ~_HWMOD_NO_MPU_PORT; break; } @@ -1113,10 +1091,7 @@ static struct omap_hwmod_ocp_if *_find_mpu_rt_port(struct omap_hwmod *oh) if (!oh || oh->_int_flags & _HWMOD_NO_MPU_PORT || oh->slaves_cnt == 0) return NULL; - if (!link_registration) - return oh->slaves[oh->_mpu_port_index]; - else - return oh->_mpu_port; + return oh->_mpu_port; }; /** @@ -2104,16 +2079,15 @@ static int __init _init(struct omap_hwmod *oh, void *data) static void __init _setup_iclk_autoidle(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - struct list_head *p = NULL; + struct list_head *p; int i = 0; if (oh->_state != _HWMOD_STATE_INITIALIZED) return; - if (link_registration) - p = oh->slave_ports.next; + p = oh->slave_ports.next; while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, &i); if (!os->_clk) continue; @@ -2583,34 +2557,6 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), return ret; } -/** - * omap_hwmod_register - register an array of hwmods - * @ohs: pointer to an array of omap_hwmods to register - * - * Intended to be called early in boot before the clock framework is - * initialized. If @ohs is not null, will register all omap_hwmods - * listed in @ohs that are valid for this chip. Returns 0. - */ -int __init omap_hwmod_register(struct omap_hwmod **ohs) -{ - int r, i; - - if (link_registration) - return -EINVAL; - - if (!ohs) - return 0; - - i = 0; - do { - r = _register(ohs[i]); - WARN(r, "omap_hwmod: %s: _register returned %d\n", ohs[i]->name, - r); - } while (ohs[++i]); - - return 0; -} - /** * omap_hwmod_register_links - register an array of hwmod links * @ois: pointer to an array of omap_hwmod_ocp_if to register @@ -2626,8 +2572,6 @@ int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois) if (!ois) return 0; - link_registration = true; - if (!linkspace) { if (_alloc_linkspace(ois)) { pr_err("omap_hwmod: could not allocate link space\n"); @@ -2888,17 +2832,16 @@ int omap_hwmod_reset(struct omap_hwmod *oh) int omap_hwmod_count_resources(struct omap_hwmod *oh) { struct omap_hwmod_ocp_if *os; - struct list_head *p = NULL; + struct list_head *p; int ret; int i = 0; ret = _count_mpu_irqs(oh) + _count_sdma_reqs(oh); - if (link_registration) - p = oh->slave_ports.next; + p = oh->slave_ports.next; while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, &i); ret += _count_ocp_if_addr_spaces(os); } @@ -2918,7 +2861,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh) int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) { struct omap_hwmod_ocp_if *os; - struct list_head *p = NULL; + struct list_head *p; int i, j, mpu_irqs_cnt, sdma_reqs_cnt, addr_cnt; int r = 0; @@ -2942,12 +2885,11 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) r++; } - if (link_registration) - p = oh->slave_ports.next; + p = oh->slave_ports.next; i = 0; while (i < oh->slaves_cnt) { - os = _fetch_next_ocp_if(&p, oh->slaves, &i); + os = _fetch_next_ocp_if(&p, &i); addr_cnt = _count_ocp_if_addr_spaces(os); for (j = 0; j < addr_cnt; j++) { diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 09679032603c..14dde32cd406 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -504,12 +504,9 @@ struct omap_hwmod_link { * @_clk: pointer to the main struct clk (filled in at runtime) * @opt_clks: other device clocks that drivers can request (0..*) * @voltdm: pointer to voltage domain (filled in at runtime) - * @masters: ptr to array of OCP ifs that this hwmod can initiate on - * @slaves: ptr to array of OCP ifs that this hwmod can respond on * @dev_attr: arbitrary device attributes that can be passed to the driver * @_sysc_cache: internal-use hwmod flags * @_mpu_rt_va: cached register target start address (internal use) - * @_mpu_port_index: cached MPU register target slave ID (internal use) * @_mpu_port: cached MPU register target slave (internal use) * @opt_clks_cnt: number of @opt_clks * @master_cnt: number of @master entries @@ -549,8 +546,6 @@ struct omap_hwmod { struct omap_hwmod_opt_clk *opt_clks; char *clkdm_name; struct clockdomain *clkdm; - struct omap_hwmod_ocp_if **masters; /* connect to *_IA */ - struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */ struct list_head master_ports; /* connect to *_IA */ struct list_head slave_ports; /* connect to *_TA */ void *dev_attr; @@ -560,7 +555,6 @@ struct omap_hwmod { struct list_head node; struct omap_hwmod_ocp_if *_mpu_port; u16 flags; - u8 _mpu_port_index; u8 response_lat; u8 rst_lines_cnt; u8 opt_clks_cnt; @@ -572,7 +566,6 @@ struct omap_hwmod { u8 _postsetup_state; }; -int omap_hwmod_register(struct omap_hwmod **ohs); struct omap_hwmod *omap_hwmod_lookup(const char *name); int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), void *data); -- cgit v1.2.3 From 42b9e38728d5b810b2f1c1d15d6ee170c8eca9d6 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 19 Apr 2012 13:33:54 -0600 Subject: ARM: OMAP4: hwmod data: add some interconnect-related IP blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the SL2 interface IP block and interconnect data. The SL2 is related to the IVA-HD subsystem. Add IP block and interconnect data for the C2C ("Chip-to-chip") interconnect. This can provide a direct system interconnect link to other devices stacked on the OMAP package. Add the ELM IP block and interconnect data. The ELM can be used to locate errors in NAND flash connected to the GPMC. Signed-off-by: Paul Walmsley Signed-off-by: Benoît Cousson --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 224 ++++++++++++++++++++++++++- arch/arm/plat-omap/include/plat/omap_hwmod.h | 1 + 2 files changed, 221 insertions(+), 4 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 330cafe56564..62b283f3b330 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -50,6 +50,27 @@ * IP blocks */ +/* + * 'c2c_target_fw' class + * instance(s): c2c_target_fw + */ +static struct omap_hwmod_class omap44xx_c2c_target_fw_hwmod_class = { + .name = "c2c_target_fw", +}; + +/* c2c_target_fw */ +static struct omap_hwmod omap44xx_c2c_target_fw_hwmod = { + .name = "c2c_target_fw", + .class = &omap44xx_c2c_target_fw_hwmod_class, + .clkdm_name = "d2d_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_D2D_SAD2D_FW_CONTEXT_OFFSET, + }, + }, +}; + /* * 'dmm' class * instance(s): dmm @@ -249,8 +270,6 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = { * - They still need to be validated with the driver * properly adapted to omap_hwmod / omap_device * - * c2c - * c2c_target_fw * cm_core * cm_core_aon * ctrl_module_core @@ -260,7 +279,6 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = { * debugss * efuse_ctrl_cust * efuse_ctrl_std - * elm * mpu_c0 * mpu_c1 * ocmc_ram @@ -269,7 +287,6 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = { * prcm_mpu * prm * scrm - * sl2if * usb_host_fs * usb_host_hs * usb_phy_cm @@ -331,6 +348,41 @@ static struct omap_hwmod omap44xx_aess_hwmod = { }, }; +/* + * 'c2c' class + * chip 2 chip interface used to plug the ape soc (omap) with an external modem + * soc + */ + +static struct omap_hwmod_class omap44xx_c2c_hwmod_class = { + .name = "c2c", +}; + +/* c2c */ +static struct omap_hwmod_irq_info omap44xx_c2c_irqs[] = { + { .irq = 88 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap44xx_c2c_sdma_reqs[] = { + { .dma_req = 68 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap44xx_c2c_hwmod = { + .name = "c2c", + .class = &omap44xx_c2c_hwmod_class, + .clkdm_name = "d2d_clkdm", + .mpu_irqs = omap44xx_c2c_irqs, + .sdma_reqs = omap44xx_c2c_sdma_reqs, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_D2D_SAD2D_CONTEXT_OFFSET, + }, + }, +}; + /* * 'counter' class * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock @@ -806,6 +858,46 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { }, }; +/* + * 'elm' class + * bch error location module + */ + +static struct omap_hwmod_class_sysconfig omap44xx_elm_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_elm_hwmod_class = { + .name = "elm", + .sysc = &omap44xx_elm_sysc, +}; + +/* elm */ +static struct omap_hwmod_irq_info omap44xx_elm_irqs[] = { + { .irq = 4 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap44xx_elm_hwmod = { + .name = "elm", + .class = &omap44xx_elm_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .mpu_irqs = omap44xx_elm_irqs, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_ELM_CONTEXT_OFFSET, + }, + }, +}; + /* * 'emif' class * external memory interface no1 @@ -2296,6 +2388,29 @@ static struct omap_hwmod omap44xx_mpu_hwmod = { }, }; +/* + * 'sl2if' class + * shared level 2 memory interface + */ + +static struct omap_hwmod_class omap44xx_sl2if_hwmod_class = { + .name = "sl2if", +}; + +/* sl2if */ +static struct omap_hwmod omap44xx_sl2if_hwmod = { + .name = "sl2if", + .class = &omap44xx_sl2if_hwmod_class, + .clkdm_name = "ivahd_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + /* * 'slimbus' class * bidirectional, multi-drop, multi-channel two-line serial interface between @@ -3222,6 +3337,32 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = { * interfaces */ +static struct omap_hwmod_addr_space omap44xx_c2c_target_fw_addrs[] = { + { + .pa_start = 0x4a204000, + .pa_end = 0x4a2040ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* c2c -> c2c_target_fw */ +static struct omap_hwmod_ocp_if omap44xx_c2c__c2c_target_fw = { + .master = &omap44xx_c2c_hwmod, + .slave = &omap44xx_c2c_target_fw_hwmod, + .clk = "div_core_ck", + .addr = omap44xx_c2c_target_fw_addrs, + .user = OCP_USER_MPU, +}; + +/* l4_cfg -> c2c_target_fw */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__c2c_target_fw = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_c2c_target_fw_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* l3_main_1 -> dmm */ static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dmm = { .master = &omap44xx_l3_main_1_hwmod, @@ -3248,6 +3389,14 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = { .user = OCP_USER_MPU, }; +/* c2c -> emif_fw */ +static struct omap_hwmod_ocp_if omap44xx_c2c__emif_fw = { + .master = &omap44xx_c2c_hwmod, + .slave = &omap44xx_emif_fw_hwmod, + .clk = "div_core_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* dmm -> emif_fw */ static struct omap_hwmod_ocp_if omap44xx_dmm__emif_fw = { .master = &omap44xx_dmm_hwmod, @@ -3356,6 +3505,14 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = { .user = OCP_USER_MPU, }; +/* c2c_target_fw -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_c2c_target_fw__l3_main_2 = { + .master = &omap44xx_c2c_target_fw_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* dma_system -> l3_main_2 */ static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = { .master = &omap44xx_dma_system_hwmod, @@ -3588,6 +3745,14 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess_dma = { .user = OCP_USER_SDMA, }; +/* l3_main_2 -> c2c */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__c2c = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_c2c_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_counter_32k_addrs[] = { { .pa_start = 0x4a304000, @@ -3670,6 +3835,14 @@ static struct omap_hwmod_ocp_if omap44xx_dsp__iva = { .user = OCP_USER_DSP, }; +/* dsp -> sl2if */ +static struct omap_hwmod_ocp_if omap44xx_dsp__sl2if = { + .master = &omap44xx_dsp_hwmod, + .slave = &omap44xx_sl2if_hwmod, + .clk = "dpll_iva_m5x2_ck", + .user = OCP_USER_DSP, +}; + /* l4_cfg -> dsp */ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dsp = { .master = &omap44xx_l4_cfg_hwmod, @@ -3930,6 +4103,24 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = { .user = OCP_USER_MPU, }; +static struct omap_hwmod_addr_space omap44xx_elm_addrs[] = { + { + .pa_start = 0x48078000, + .pa_end = 0x48078fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> elm */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_elm_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_elm_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_emif1_addrs[] = { { .pa_start = 0x4c000000, @@ -4262,6 +4453,14 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* iva -> sl2if */ +static struct omap_hwmod_ocp_if omap44xx_iva__sl2if = { + .master = &omap44xx_iva_hwmod, + .slave = &omap44xx_sl2if_hwmod, + .clk = "dpll_iva_m5x2_ck", + .user = OCP_USER_IVA, +}; + static struct omap_hwmod_addr_space omap44xx_iva_addrs[] = { { .pa_start = 0x5a000000, @@ -4682,6 +4881,14 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc5 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l3_main_2 -> sl2if */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sl2if = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_sl2if_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_slimbus1_addrs[] = { { .pa_start = 0x4012c000, @@ -5271,8 +5478,11 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3_dma = { }; static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { + &omap44xx_c2c__c2c_target_fw, + &omap44xx_l4_cfg__c2c_target_fw, &omap44xx_l3_main_1__dmm, &omap44xx_mpu__dmm, + &omap44xx_c2c__emif_fw, &omap44xx_dmm__emif_fw, &omap44xx_l4_cfg__emif_fw, &omap44xx_iva__l3_instr, @@ -5284,6 +5494,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_mmc1__l3_main_1, &omap44xx_mmc2__l3_main_1, &omap44xx_mpu__l3_main_1, + &omap44xx_c2c_target_fw__l3_main_2, &omap44xx_dma_system__l3_main_2, &omap44xx_fdif__l3_main_2, &omap44xx_gpu__l3_main_2, @@ -5308,11 +5519,13 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_mpu__mpu_private, &omap44xx_l4_abe__aess, &omap44xx_l4_abe__aess_dma, + &omap44xx_l3_main_2__c2c, &omap44xx_l4_wkup__counter_32k, &omap44xx_l4_cfg__dma_system, &omap44xx_l4_abe__dmic, &omap44xx_l4_abe__dmic_dma, &omap44xx_dsp__iva, + &omap44xx_dsp__sl2if, &omap44xx_l4_cfg__dsp, &omap44xx_l3_main_2__dss, &omap44xx_l4_per__dss, @@ -5328,6 +5541,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_per__dss_rfbi, &omap44xx_l3_main_2__dss_venc, &omap44xx_l4_per__dss_venc, + &omap44xx_l4_per__elm, &omap44xx_emif_fw__emif1, &omap44xx_emif_fw__emif2, &omap44xx_l4_cfg__fdif, @@ -5347,6 +5561,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_per__i2c4, &omap44xx_l3_main_2__ipu, &omap44xx_l3_main_2__iss, + &omap44xx_iva__sl2if, &omap44xx_l3_main_2__iva, &omap44xx_l4_wkup__kbd, &omap44xx_l4_cfg__mailbox, @@ -5370,6 +5585,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_per__mmc3, &omap44xx_l4_per__mmc4, &omap44xx_l4_per__mmc5, + &omap44xx_l3_main_2__sl2if, &omap44xx_l4_abe__slimbus1, &omap44xx_l4_abe__slimbus1_dma, &omap44xx_l4_per__slimbus2, diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 14dde32cd406..c835b7194ff5 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -214,6 +214,7 @@ struct omap_hwmod_addr_space { #define OCP_USER_MPU (1 << 0) #define OCP_USER_SDMA (1 << 1) #define OCP_USER_DSP (1 << 2) +#define OCP_USER_IVA (1 << 3) /* omap_hwmod_ocp_if.flags bits */ #define OCPIF_SWSUP_IDLE (1 << 0) -- cgit v1.2.3