aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/include/mach
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2009-09-03 13:14:03 -0400
committerpaul <paul@twilight.(none)>2009-09-03 13:14:03 -0400
commit63c852384125ca0eff0e695f92cbbd439bed4aa3 (patch)
treead81b262c5b05aaa546ffdd4e43a3c31616f347f /arch/arm/plat-omap/include/mach
parentb3c6df3ab2b17cd7ddf927d39a64f235b25ac8d4 (diff)
OMAP2/3/4: create omap_hwmod layer
OMAP SoCs can be considered a collection of hardware IP blocks connected by various interconnects. The bus topology and device integration data is somewhat more complex than platform_device can encode. This patch creates code and structures to manage information about OMAP on-chip devices ("hardware modules") and their integration to the rest of the chip. Hardware module data is intended to be generated dynamically from the TI hardware database for the OMAP4 chips and beyond, easing Linux support for new chip variants. This code currently: - resets and configures all hardware modules upon startup, reducing bootloader dependencies; - provides hooks for Linux driver model code to enable, idle, and shutdown hardware modules (forthcoming patch); - waits for hardware modules to leave idle once their clocks are enabled and OCP_SYSCONFIG bits are set appropriately. - provides a means to pass arbitrary IP block configuration data (e.g., FIFO size) to the device driver (via the dev_attr void pointer) In the future this code is intended to: - estimate interconnect bandwidth and latency characteristics to ensure constraints are satisfied during DVFS - provide *GRPSEL bit data to the powerdomain code - handle pin/ball muxing for devices - generate IO mapping information dynamically - supply device firewall configuration data - provide hardware module data to other on-chip coprocessor software - allow the removal of the "disable unused clocks" code in the OMAP2/3 clock code This patch represents a collaborative effort involving many people from TI, Nokia, and the Linux-OMAP community. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Benoit Cousson <b-cousson@ti.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> Cc: Tony Lindgren <tony@atomide.com> Cc: Rajendra Nayak <rnayak@ti.com> Cc: Vikram Pandita <vikram.pandita@ti.com> Cc: Sakari Poussa <sakari.poussa@nokia.com> Cc: Anand Sawant <sawant@ti.com> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com> Cc: Eric Thomas <ethomas@ti.com> Cc: Richard Woodruff <r-woodruff2@ti.com>
Diffstat (limited to 'arch/arm/plat-omap/include/mach')
-rw-r--r--arch/arm/plat-omap/include/mach/omap_hwmod.h447
1 files changed, 447 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/include/mach/omap_hwmod.h b/arch/arm/plat-omap/include/mach/omap_hwmod.h
new file mode 100644
index 000000000000..1f79c20e2929
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/omap_hwmod.h
@@ -0,0 +1,447 @@
1/*
2 * omap_hwmod macros, structures
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Paul Walmsley
6 *
7 * Created in collaboration with (alphabetical order): Benoit Cousson,
8 * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
9 * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * These headers and macros are used to define OMAP on-chip module
16 * data and their integration with other OMAP modules and Linux.
17 *
18 * References:
19 * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
20 * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
21 * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
22 * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
23 * - Open Core Protocol Specification 2.2
24 *
25 * To do:
26 * - add interconnect error log structures
27 * - add pinmuxing
28 * - init_conn_id_bit (CONNID_BIT_VECTOR)
29 * - implement default hwmod SMS/SDRC flags?
30 *
31 */
32#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
33#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
34
35#include <linux/kernel.h>
36#include <linux/ioport.h>
37
38#include <mach/cpu.h>
39
40struct omap_device;
41
42/* OCP SYSCONFIG bit shifts/masks */
43#define SYSC_MIDLEMODE_SHIFT 12
44#define SYSC_MIDLEMODE_MASK (0x3 << SYSC_MIDLEMODE_SHIFT)
45#define SYSC_CLOCKACTIVITY_SHIFT 8
46#define SYSC_CLOCKACTIVITY_MASK (0x3 << SYSC_CLOCKACTIVITY_SHIFT)
47#define SYSC_SIDLEMODE_SHIFT 3
48#define SYSC_SIDLEMODE_MASK (0x3 << SYSC_SIDLEMODE_SHIFT)
49#define SYSC_ENAWAKEUP_SHIFT 2
50#define SYSC_ENAWAKEUP_MASK (1 << SYSC_ENAWAKEUP_SHIFT)
51#define SYSC_SOFTRESET_SHIFT 1
52#define SYSC_SOFTRESET_MASK (1 << SYSC_SOFTRESET_SHIFT)
53
54/* OCP SYSSTATUS bit shifts/masks */
55#define SYSS_RESETDONE_SHIFT 0
56#define SYSS_RESETDONE_MASK (1 << SYSS_RESETDONE_SHIFT)
57
58/* Master standby/slave idle mode flags */
59#define HWMOD_IDLEMODE_FORCE (1 << 0)
60#define HWMOD_IDLEMODE_NO (1 << 1)
61#define HWMOD_IDLEMODE_SMART (1 << 2)
62
63
64/**
65 * struct omap_hwmod_dma_info - MPU address space handled by the hwmod
66 * @name: name of the DMA channel (module local name)
67 * @dma_ch: DMA channel ID
68 *
69 * @name should be something short, e.g., "tx" or "rx". It is for use
70 * by platform_get_resource_byname(). It is defined locally to the
71 * hwmod.
72 */
73struct omap_hwmod_dma_info {
74 const char *name;
75 u16 dma_ch;
76};
77
78/**
79 * struct omap_hwmod_opt_clk - optional clocks used by this hwmod
80 * @role: "sys", "32k", "tv", etc -- for use in clk_get()
81 * @clkdev_dev_id: opt clock: clkdev dev_id string
82 * @clkdev_con_id: opt clock: clkdev con_id string
83 * @_clk: pointer to the struct clk (filled in at runtime)
84 *
85 * The module's interface clock and main functional clock should not
86 * be added as optional clocks.
87 */
88struct omap_hwmod_opt_clk {
89 const char *role;
90 const char *clkdev_dev_id;
91 const char *clkdev_con_id;
92 struct clk *_clk;
93};
94
95
96/* omap_hwmod_omap2_firewall.flags bits */
97#define OMAP_FIREWALL_L3 (1 << 0)
98#define OMAP_FIREWALL_L4 (1 << 1)
99
100/**
101 * struct omap_hwmod_omap2_firewall - OMAP2/3 device firewall data
102 * @l3_perm_bit: bit shift for L3_PM_*_PERMISSION_*
103 * @l4_fw_region: L4 firewall region ID
104 * @l4_prot_group: L4 protection group ID
105 * @flags: (see omap_hwmod_omap2_firewall.flags macros above)
106 */
107struct omap_hwmod_omap2_firewall {
108 u8 l3_perm_bit;
109 u8 l4_fw_region;
110 u8 l4_prot_group;
111 u8 flags;
112};
113
114
115/*
116 * omap_hwmod_addr_space.flags bits
117 *
118 * ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init.
119 * ADDR_TYPE_RT: Address space contains module register target data.
120 */
121#define ADDR_MAP_ON_INIT (1 << 0)
122#define ADDR_TYPE_RT (1 << 1)
123
124/**
125 * struct omap_hwmod_addr_space - MPU address space handled by the hwmod
126 * @pa_start: starting physical address
127 * @pa_end: ending physical address
128 * @flags: (see omap_hwmod_addr_space.flags macros above)
129 *
130 * Address space doesn't necessarily follow physical interconnect
131 * structure. GPMC is one example.
132 */
133struct omap_hwmod_addr_space {
134 u32 pa_start;
135 u32 pa_end;
136 u8 flags;
137};
138
139
140/*
141 * omap_hwmod_ocp_if.user bits: these indicate the initiators that use this
142 * interface to interact with the hwmod. Used to add sleep dependencies
143 * when the module is enabled or disabled.
144 */
145#define OCP_USER_MPU (1 << 0)
146#define OCP_USER_SDMA (1 << 1)
147
148/* omap_hwmod_ocp_if.flags bits */
149#define OCPIF_HAS_IDLEST (1 << 0)
150#define OCPIF_SWSUP_IDLE (1 << 1)
151#define OCPIF_CAN_BURST (1 << 2)
152
153/**
154 * struct omap_hwmod_ocp_if - OCP interface data
155 * @master: struct omap_hwmod that initiates OCP transactions on this link
156 * @slave: struct omap_hwmod that responds to OCP transactions on this link
157 * @addr: address space associated with this link
158 * @clkdev_dev_id: interface clock: clkdev dev_id string
159 * @clkdev_con_id: interface clock: clkdev con_id string
160 * @_clk: pointer to the interface struct clk (filled in at runtime)
161 * @fw: interface firewall data
162 * @addr_cnt: ARRAY_SIZE(@addr)
163 * @width: OCP data width
164 * @thread_cnt: number of threads
165 * @max_burst_len: maximum burst length in @width sized words (0 if unlimited)
166 * @user: initiators using this interface (see OCP_USER_* macros above)
167 * @flags: OCP interface flags (see OCPIF_* macros above)
168 *
169 * It may also be useful to add a tag_cnt field for OCP2.x devices.
170 *
171 * Parameter names beginning with an underscore are managed internally by
172 * the omap_hwmod code and should not be set during initialization.
173 */
174struct omap_hwmod_ocp_if {
175 struct omap_hwmod *master;
176 struct omap_hwmod *slave;
177 struct omap_hwmod_addr_space *addr;
178 const char *clkdev_dev_id;
179 const char *clkdev_con_id;
180 struct clk *_clk;
181 union {
182 struct omap_hwmod_omap2_firewall omap2;
183 } fw;
184 u8 addr_cnt;
185 u8 width;
186 u8 thread_cnt;
187 u8 max_burst_len;
188 u8 user;
189 u8 flags;
190};
191
192
193/* Macros for use in struct omap_hwmod_sysconfig */
194
195/* Flags for use in omap_hwmod_sysconfig.idlemodes */
196#define MASTER_STANDBY_SHIFT 2
197#define SLAVE_IDLE_SHIFT 0
198#define SIDLE_FORCE (HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT)
199#define SIDLE_NO (HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT)
200#define SIDLE_SMART (HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT)
201#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
202#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
203#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
204
205/* omap_hwmod_sysconfig.sysc_flags capability flags */
206#define SYSC_HAS_AUTOIDLE (1 << 0)
207#define SYSC_HAS_SOFTRESET (1 << 1)
208#define SYSC_HAS_ENAWAKEUP (1 << 2)
209#define SYSC_HAS_EMUFREE (1 << 3)
210#define SYSC_HAS_CLOCKACTIVITY (1 << 4)
211#define SYSC_HAS_SIDLEMODE (1 << 5)
212#define SYSC_HAS_MIDLEMODE (1 << 6)
213#define SYSS_MISSING (1 << 7)
214
215/* omap_hwmod_sysconfig.clockact flags */
216#define CLOCKACT_TEST_BOTH 0x0
217#define CLOCKACT_TEST_MAIN 0x1
218#define CLOCKACT_TEST_ICLK 0x2
219#define CLOCKACT_TEST_NONE 0x3
220
221/**
222 * struct omap_hwmod_sysconfig - hwmod OCP_SYSCONFIG/OCP_SYSSTATUS data
223 * @rev_offs: IP block revision register offset (from module base addr)
224 * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
225 * @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
226 * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
227 * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
228 * @clockact: the default value of the module CLOCKACTIVITY bits
229 *
230 * @clockact describes to the module which clocks are likely to be
231 * disabled when the PRCM issues its idle request to the module. Some
232 * modules have separate clockdomains for the interface clock and main
233 * functional clock, and can check whether they should acknowledge the
234 * idle request based on the internal module functionality that has
235 * been associated with the clocks marked in @clockact. This field is
236 * only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below)
237 *
238 */
239struct omap_hwmod_sysconfig {
240 u16 rev_offs;
241 u16 sysc_offs;
242 u16 syss_offs;
243 u8 idlemodes;
244 u8 sysc_flags;
245 u8 clockact;
246};
247
248/**
249 * struct omap_hwmod_omap2_prcm - OMAP2/3-specific PRCM data
250 * @module_offs: PRCM submodule offset from the start of the PRM/CM
251 * @prcm_reg_id: PRCM register ID (e.g., 3 for CM_AUTOIDLE3)
252 * @module_bit: register bit shift for AUTOIDLE, WKST, WKEN, GRPSEL regs
253 * @idlest_reg_id: IDLEST register ID (e.g., 3 for CM_IDLEST3)
254 * @idlest_idle_bit: register bit shift for CM_IDLEST slave idle bit
255 * @idlest_stdby_bit: register bit shift for CM_IDLEST master standby bit
256 *
257 * @prcm_reg_id and @module_bit are specific to the AUTOIDLE, WKST,
258 * WKEN, GRPSEL registers. In an ideal world, no extra information
259 * would be needed for IDLEST information, but alas, there are some
260 * exceptions, so @idlest_reg_id, @idlest_idle_bit, @idlest_stdby_bit
261 * are needed for the IDLEST registers (c.f. 2430 I2CHS, 3430 USBHOST)
262 */
263struct omap_hwmod_omap2_prcm {
264 s16 module_offs;
265 u8 prcm_reg_id;
266 u8 module_bit;
267 u8 idlest_reg_id;
268 u8 idlest_idle_bit;
269 u8 idlest_stdby_bit;
270};
271
272
273/**
274 * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
275 * @module_offs: PRCM submodule offset from the start of the PRM/CM1/CM2
276 * @device_offs: device register offset from @module_offs
277 * @submodule_wkdep_bit: bit shift of the WKDEP range
278 */
279struct omap_hwmod_omap4_prcm {
280 u32 module_offs;
281 u16 device_offs;
282 u8 submodule_wkdep_bit;
283};
284
285
286/*
287 * omap_hwmod.flags definitions
288 *
289 * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
290 * of idle, rather than relying on module smart-idle
291 * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
292 * of standby, rather than relying on module smart-standby
293 * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
294 * SDRAM controller, etc.
295 * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
296 * controller, etc.
297 * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
298 */
299#define HWMOD_SWSUP_SIDLE (1 << 0)
300#define HWMOD_SWSUP_MSTANDBY (1 << 1)
301#define HWMOD_INIT_NO_RESET (1 << 2)
302#define HWMOD_INIT_NO_IDLE (1 << 3)
303#define HWMOD_SET_DEFAULT_CLOCKACT (1 << 4)
304
305/*
306 * omap_hwmod._int_flags definitions
307 * These are for internal use only and are managed by the omap_hwmod code.
308 *
309 * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
310 * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP
311 * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
312 */
313#define _HWMOD_NO_MPU_PORT (1 << 0)
314#define _HWMOD_WAKEUP_ENABLED (1 << 1)
315#define _HWMOD_SYSCONFIG_LOADED (1 << 2)
316
317/*
318 * omap_hwmod._state definitions
319 *
320 * INITIALIZED: reset (optionally), initialized, enabled, disabled
321 * (optionally)
322 *
323 *
324 */
325#define _HWMOD_STATE_UNKNOWN 0
326#define _HWMOD_STATE_REGISTERED 1
327#define _HWMOD_STATE_CLKS_INITED 2
328#define _HWMOD_STATE_INITIALIZED 3
329#define _HWMOD_STATE_ENABLED 4
330#define _HWMOD_STATE_IDLE 5
331#define _HWMOD_STATE_DISABLED 6
332
333/**
334 * struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks)
335 * @name: name of the hwmod
336 * @od: struct omap_device currently associated with this hwmod (internal use)
337 * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
338 * @sdma_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt)
339 * @prcm: PRCM data pertaining to this hwmod
340 * @clkdev_dev_id: main clock: clkdev dev_id string
341 * @clkdev_con_id: main clock: clkdev con_id string
342 * @_clk: pointer to the main struct clk (filled in at runtime)
343 * @opt_clks: other device clocks that drivers can request (0..*)
344 * @masters: ptr to array of OCP ifs that this hwmod can initiate on
345 * @slaves: ptr to array of OCP ifs that this hwmod can respond on
346 * @sysconfig: device SYSCONFIG/SYSSTATUS register data
347 * @dev_attr: arbitrary device attributes that can be passed to the driver
348 * @_sysc_cache: internal-use hwmod flags
349 * @_rt_va: cached register target start address (internal use)
350 * @_mpu_port_index: cached MPU register target slave ID (internal use)
351 * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
352 * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
353 * @mpu_irqs_cnt: number of @mpu_irqs
354 * @sdma_chs_cnt: number of @sdma_chs
355 * @opt_clks_cnt: number of @opt_clks
356 * @master_cnt: number of @master entries
357 * @slaves_cnt: number of @slave entries
358 * @response_lat: device OCP response latency (in interface clock cycles)
359 * @_int_flags: internal-use hwmod flags
360 * @_state: internal-use hwmod state
361 * @flags: hwmod flags (documented below)
362 * @omap_chip: OMAP chips this hwmod is present on
363 * @node: list node for hwmod list (internal use)
364 *
365 * @clkdev_dev_id, @clkdev_con_id, and @clk all refer to this module's "main
366 * clock," which for our purposes is defined as "the functional clock needed
367 * for register accesses to complete." Modules may not have a main clock if
368 * the interface clock also serves as a main clock.
369 *
370 * Parameter names beginning with an underscore are managed internally by
371 * the omap_hwmod code and should not be set during initialization.
372 */
373struct omap_hwmod {
374 const char *name;
375 struct omap_device *od;
376 u8 *mpu_irqs;
377 struct omap_hwmod_dma_info *sdma_chs;
378 union {
379 struct omap_hwmod_omap2_prcm omap2;
380 struct omap_hwmod_omap4_prcm omap4;
381 } prcm;
382 const char *clkdev_dev_id;
383 const char *clkdev_con_id;
384 struct clk *_clk;
385 struct omap_hwmod_opt_clk *opt_clks;
386 struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
387 struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
388 struct omap_hwmod_sysconfig *sysconfig;
389 void *dev_attr;
390 u32 _sysc_cache;
391 void __iomem *_rt_va;
392 struct list_head node;
393 u16 flags;
394 u8 _mpu_port_index;
395 u8 msuspendmux_reg_id;
396 u8 msuspendmux_shift;
397 u8 response_lat;
398 u8 mpu_irqs_cnt;
399 u8 sdma_chs_cnt;
400 u8 opt_clks_cnt;
401 u8 masters_cnt;
402 u8 slaves_cnt;
403 u8 hwmods_cnt;
404 u8 _int_flags;
405 u8 _state;
406 const struct omap_chip_id omap_chip;
407};
408
409int omap_hwmod_init(struct omap_hwmod **ohs);
410int omap_hwmod_register(struct omap_hwmod *oh);
411int omap_hwmod_unregister(struct omap_hwmod *oh);
412struct omap_hwmod *omap_hwmod_lookup(const char *name);
413int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh));
414int omap_hwmod_late_init(void);
415
416int omap_hwmod_enable(struct omap_hwmod *oh);
417int omap_hwmod_idle(struct omap_hwmod *oh);
418int omap_hwmod_shutdown(struct omap_hwmod *oh);
419
420int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
421int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
422
423int omap_hwmod_reset(struct omap_hwmod *oh);
424void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
425
426void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs);
427u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs);
428
429int omap_hwmod_count_resources(struct omap_hwmod *oh);
430int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
431
432struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
433
434int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
435 struct omap_hwmod *init_oh);
436int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
437 struct omap_hwmod *init_oh);
438
439int omap_hwmod_set_clockact_both(struct omap_hwmod *oh);
440int omap_hwmod_set_clockact_main(struct omap_hwmod *oh);
441int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh);
442int omap_hwmod_set_clockact_none(struct omap_hwmod *oh);
443
444int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
445int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
446
447#endif