diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/plat-nomadik | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'arch/arm/plat-nomadik')
-rw-r--r-- | arch/arm/plat-nomadik/Kconfig | 24 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/include/plat/gpio.h | 96 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/include/plat/i2c.h | 39 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/include/plat/mtu.h | 54 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/include/plat/pincfg.h | 144 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/include/plat/ske.h | 50 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/include/plat/ste_dma40.h | 219 | ||||
-rw-r--r-- | arch/arm/plat-nomadik/timer.c | 174 |
9 files changed, 805 insertions, 0 deletions
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig new file mode 100644 index 00000000000..ce659015535 --- /dev/null +++ b/arch/arm/plat-nomadik/Kconfig | |||
@@ -0,0 +1,24 @@ | |||
1 | # We keep common IP's here for Nomadik and other similar | ||
2 | # familiy of processors from ST-Ericsson. At the moment we have | ||
3 | # just MTU, others to follow soon. | ||
4 | |||
5 | config PLAT_NOMADIK | ||
6 | bool | ||
7 | depends on ARCH_NOMADIK || ARCH_U8500 | ||
8 | select CLKSRC_MMIO | ||
9 | default y | ||
10 | help | ||
11 | Common platform code for Nomadik and other ST-Ericsson | ||
12 | platforms. | ||
13 | |||
14 | if PLAT_NOMADIK | ||
15 | |||
16 | config HAS_MTU | ||
17 | bool | ||
18 | select HAVE_SCHED_CLOCK | ||
19 | help | ||
20 | Support for Multi Timer Unit. MTU provides access | ||
21 | to multiple interrupt generating programmable | ||
22 | 32-bit free running decrementing counters. | ||
23 | |||
24 | endif | ||
diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile new file mode 100644 index 00000000000..37c7cdd0f8f --- /dev/null +++ b/arch/arm/plat-nomadik/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # arch/arm/plat-nomadik/Makefile | ||
2 | # Copyright 2009 ST-Ericsson | ||
3 | # Licensed under GPLv2 | ||
4 | |||
5 | obj-$(CONFIG_HAS_MTU) += timer.o | ||
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h new file mode 100644 index 00000000000..d5d7e651269 --- /dev/null +++ b/arch/arm/plat-nomadik/include/plat/gpio.h | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Structures and registers for GPIO access in the Nomadik SoC | ||
3 | * | ||
4 | * Copyright (C) 2008 STMicroelectronics | ||
5 | * Author: Prafulla WADASKAR <prafulla.wadaskar@st.com> | ||
6 | * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #ifndef __ASM_PLAT_GPIO_H | ||
13 | #define __ASM_PLAT_GPIO_H | ||
14 | |||
15 | #include <asm-generic/gpio.h> | ||
16 | |||
17 | /* | ||
18 | * These currently cause a function call to happen, they may be optimized | ||
19 | * if needed by adding cpu-specific defines to identify blocks | ||
20 | * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc) | ||
21 | */ | ||
22 | #define gpio_get_value __gpio_get_value | ||
23 | #define gpio_set_value __gpio_set_value | ||
24 | #define gpio_cansleep __gpio_cansleep | ||
25 | #define gpio_to_irq __gpio_to_irq | ||
26 | |||
27 | /* | ||
28 | * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving | ||
29 | * the "gpio" namespace for generic and cross-machine functions | ||
30 | */ | ||
31 | |||
32 | /* Register in the logic block */ | ||
33 | #define NMK_GPIO_DAT 0x00 | ||
34 | #define NMK_GPIO_DATS 0x04 | ||
35 | #define NMK_GPIO_DATC 0x08 | ||
36 | #define NMK_GPIO_PDIS 0x0c | ||
37 | #define NMK_GPIO_DIR 0x10 | ||
38 | #define NMK_GPIO_DIRS 0x14 | ||
39 | #define NMK_GPIO_DIRC 0x18 | ||
40 | #define NMK_GPIO_SLPC 0x1c | ||
41 | #define NMK_GPIO_AFSLA 0x20 | ||
42 | #define NMK_GPIO_AFSLB 0x24 | ||
43 | |||
44 | #define NMK_GPIO_RIMSC 0x40 | ||
45 | #define NMK_GPIO_FIMSC 0x44 | ||
46 | #define NMK_GPIO_IS 0x48 | ||
47 | #define NMK_GPIO_IC 0x4c | ||
48 | #define NMK_GPIO_RWIMSC 0x50 | ||
49 | #define NMK_GPIO_FWIMSC 0x54 | ||
50 | #define NMK_GPIO_WKS 0x58 | ||
51 | |||
52 | /* Alternate functions: function C is set in hw by setting both A and B */ | ||
53 | #define NMK_GPIO_ALT_GPIO 0 | ||
54 | #define NMK_GPIO_ALT_A 1 | ||
55 | #define NMK_GPIO_ALT_B 2 | ||
56 | #define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B) | ||
57 | |||
58 | /* Pull up/down values */ | ||
59 | enum nmk_gpio_pull { | ||
60 | NMK_GPIO_PULL_NONE, | ||
61 | NMK_GPIO_PULL_UP, | ||
62 | NMK_GPIO_PULL_DOWN, | ||
63 | }; | ||
64 | |||
65 | /* Sleep mode */ | ||
66 | enum nmk_gpio_slpm { | ||
67 | NMK_GPIO_SLPM_INPUT, | ||
68 | NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT, | ||
69 | NMK_GPIO_SLPM_NOCHANGE, | ||
70 | NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE, | ||
71 | }; | ||
72 | |||
73 | extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode); | ||
74 | extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull); | ||
75 | extern int nmk_gpio_set_mode(int gpio, int gpio_mode); | ||
76 | extern int nmk_gpio_get_mode(int gpio); | ||
77 | |||
78 | extern void nmk_gpio_wakeups_suspend(void); | ||
79 | extern void nmk_gpio_wakeups_resume(void); | ||
80 | |||
81 | extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up); | ||
82 | |||
83 | /* | ||
84 | * Platform data to register a block: only the initial gpio/irq number. | ||
85 | */ | ||
86 | struct nmk_gpio_platform_data { | ||
87 | char *name; | ||
88 | int first_gpio; | ||
89 | int first_irq; | ||
90 | int num_gpio; | ||
91 | u32 (*get_secondary_status)(unsigned int bank); | ||
92 | void (*set_ioforce)(bool enable); | ||
93 | bool supports_sleepmode; | ||
94 | }; | ||
95 | |||
96 | #endif /* __ASM_PLAT_GPIO_H */ | ||
diff --git a/arch/arm/plat-nomadik/include/plat/i2c.h b/arch/arm/plat-nomadik/include/plat/i2c.h new file mode 100644 index 00000000000..8ba70ffc31e --- /dev/null +++ b/arch/arm/plat-nomadik/include/plat/i2c.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 ST-Ericsson | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2, as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | #ifndef __PLAT_I2C_H | ||
9 | #define __PLAT_I2C_H | ||
10 | |||
11 | enum i2c_freq_mode { | ||
12 | I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */ | ||
13 | I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */ | ||
14 | I2C_FREQ_MODE_HIGH_SPEED, /* up to 3.4 Mb/s */ | ||
15 | I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */ | ||
16 | }; | ||
17 | |||
18 | /** | ||
19 | * struct nmk_i2c_controller - client specific controller configuration | ||
20 | * @clk_freq: clock frequency for the operation mode | ||
21 | * @slsu: Slave data setup time in ns. | ||
22 | * The needed setup time for three modes of operation | ||
23 | * are 250ns, 100ns and 10ns respectively thus leading | ||
24 | * to the values of 14, 6, 2 for a 48 MHz i2c clk | ||
25 | * @tft: Tx FIFO Threshold in bytes | ||
26 | * @rft: Rx FIFO Threshold in bytes | ||
27 | * @timeout Slave response timeout(ms) | ||
28 | * @sm: speed mode | ||
29 | */ | ||
30 | struct nmk_i2c_controller { | ||
31 | unsigned long clk_freq; | ||
32 | unsigned short slsu; | ||
33 | unsigned char tft; | ||
34 | unsigned char rft; | ||
35 | int timeout; | ||
36 | enum i2c_freq_mode sm; | ||
37 | }; | ||
38 | |||
39 | #endif /* __PLAT_I2C_H */ | ||
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h new file mode 100644 index 00000000000..65704a3d424 --- /dev/null +++ b/arch/arm/plat-nomadik/include/plat/mtu.h | |||
@@ -0,0 +1,54 @@ | |||
1 | #ifndef __PLAT_MTU_H | ||
2 | #define __PLAT_MTU_H | ||
3 | |||
4 | /* | ||
5 | * Guaranteed runtime conversion range in seconds for | ||
6 | * the clocksource and clockevent. | ||
7 | */ | ||
8 | #define MTU_MIN_RANGE 4 | ||
9 | |||
10 | /* should be set by the platform code */ | ||
11 | extern void __iomem *mtu_base; | ||
12 | |||
13 | /* | ||
14 | * The MTU device hosts four different counters, with 4 set of | ||
15 | * registers. These are register names. | ||
16 | */ | ||
17 | |||
18 | #define MTU_IMSC 0x00 /* Interrupt mask set/clear */ | ||
19 | #define MTU_RIS 0x04 /* Raw interrupt status */ | ||
20 | #define MTU_MIS 0x08 /* Masked interrupt status */ | ||
21 | #define MTU_ICR 0x0C /* Interrupt clear register */ | ||
22 | |||
23 | /* per-timer registers take 0..3 as argument */ | ||
24 | #define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */ | ||
25 | #define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */ | ||
26 | #define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */ | ||
27 | #define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */ | ||
28 | |||
29 | /* bits for the control register */ | ||
30 | #define MTU_CRn_ENA 0x80 | ||
31 | #define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */ | ||
32 | #define MTU_CRn_PRESCALE_MASK 0x0c | ||
33 | #define MTU_CRn_PRESCALE_1 0x00 | ||
34 | #define MTU_CRn_PRESCALE_16 0x04 | ||
35 | #define MTU_CRn_PRESCALE_256 0x08 | ||
36 | #define MTU_CRn_32BITS 0x02 | ||
37 | #define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/ | ||
38 | |||
39 | /* Other registers are usual amba/primecell registers, currently not used */ | ||
40 | #define MTU_ITCR 0xff0 | ||
41 | #define MTU_ITOP 0xff4 | ||
42 | |||
43 | #define MTU_PERIPH_ID0 0xfe0 | ||
44 | #define MTU_PERIPH_ID1 0xfe4 | ||
45 | #define MTU_PERIPH_ID2 0xfe8 | ||
46 | #define MTU_PERIPH_ID3 0xfeC | ||
47 | |||
48 | #define MTU_PCELL0 0xff0 | ||
49 | #define MTU_PCELL1 0xff4 | ||
50 | #define MTU_PCELL2 0xff8 | ||
51 | #define MTU_PCELL3 0xffC | ||
52 | |||
53 | #endif /* __PLAT_MTU_H */ | ||
54 | |||
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h new file mode 100644 index 00000000000..05a3936ae6d --- /dev/null +++ b/arch/arm/plat-nomadik/include/plat/pincfg.h | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License terms: GNU General Public License, version 2 | ||
5 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
6 | * | ||
7 | * Based on arch/arm/mach-pxa/include/mach/mfp.h: | ||
8 | * Copyright (C) 2007 Marvell International Ltd. | ||
9 | * eric miao <eric.miao@marvell.com> | ||
10 | */ | ||
11 | |||
12 | #ifndef __PLAT_PINCFG_H | ||
13 | #define __PLAT_PINCFG_H | ||
14 | |||
15 | /* | ||
16 | * pin configurations are represented by 32-bit integers: | ||
17 | * | ||
18 | * bit 0.. 8 - Pin Number (512 Pins Maximum) | ||
19 | * bit 9..10 - Alternate Function Selection | ||
20 | * bit 11..12 - Pull up/down state | ||
21 | * bit 13 - Sleep mode behaviour | ||
22 | * bit 14 - Direction | ||
23 | * bit 15 - Value (if output) | ||
24 | * bit 16..18 - SLPM pull up/down state | ||
25 | * bit 19..20 - SLPM direction | ||
26 | * bit 21..22 - SLPM Value (if output) | ||
27 | * | ||
28 | * to facilitate the definition, the following macros are provided | ||
29 | * | ||
30 | * PIN_CFG_DEFAULT - default config (0): | ||
31 | * pull up/down = disabled | ||
32 | * sleep mode = input/wakeup | ||
33 | * direction = input | ||
34 | * value = low | ||
35 | * SLPM direction = same as normal | ||
36 | * SLPM pull = same as normal | ||
37 | * SLPM value = same as normal | ||
38 | * | ||
39 | * PIN_CFG - default config with alternate function | ||
40 | * PIN_CFG_PULL - default config with alternate function and pull up/down | ||
41 | */ | ||
42 | |||
43 | typedef unsigned long pin_cfg_t; | ||
44 | |||
45 | #define PIN_NUM_MASK 0x1ff | ||
46 | #define PIN_NUM(x) ((x) & PIN_NUM_MASK) | ||
47 | |||
48 | #define PIN_ALT_SHIFT 9 | ||
49 | #define PIN_ALT_MASK (0x3 << PIN_ALT_SHIFT) | ||
50 | #define PIN_ALT(x) (((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT) | ||
51 | #define PIN_GPIO (NMK_GPIO_ALT_GPIO << PIN_ALT_SHIFT) | ||
52 | #define PIN_ALT_A (NMK_GPIO_ALT_A << PIN_ALT_SHIFT) | ||
53 | #define PIN_ALT_B (NMK_GPIO_ALT_B << PIN_ALT_SHIFT) | ||
54 | #define PIN_ALT_C (NMK_GPIO_ALT_C << PIN_ALT_SHIFT) | ||
55 | |||
56 | #define PIN_PULL_SHIFT 11 | ||
57 | #define PIN_PULL_MASK (0x3 << PIN_PULL_SHIFT) | ||
58 | #define PIN_PULL(x) (((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT) | ||
59 | #define PIN_PULL_NONE (NMK_GPIO_PULL_NONE << PIN_PULL_SHIFT) | ||
60 | #define PIN_PULL_UP (NMK_GPIO_PULL_UP << PIN_PULL_SHIFT) | ||
61 | #define PIN_PULL_DOWN (NMK_GPIO_PULL_DOWN << PIN_PULL_SHIFT) | ||
62 | |||
63 | #define PIN_SLPM_SHIFT 13 | ||
64 | #define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT) | ||
65 | #define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT) | ||
66 | #define PIN_SLPM_MAKE_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT) | ||
67 | #define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT) | ||
68 | /* These two replace the above in DB8500v2+ */ | ||
69 | #define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT) | ||
70 | #define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT) | ||
71 | |||
72 | #define PIN_DIR_SHIFT 14 | ||
73 | #define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT) | ||
74 | #define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT) | ||
75 | #define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT) | ||
76 | #define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT) | ||
77 | |||
78 | #define PIN_VAL_SHIFT 15 | ||
79 | #define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT) | ||
80 | #define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT) | ||
81 | #define PIN_VAL_LOW (0 << PIN_VAL_SHIFT) | ||
82 | #define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT) | ||
83 | |||
84 | #define PIN_SLPM_PULL_SHIFT 16 | ||
85 | #define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT) | ||
86 | #define PIN_SLPM_PULL(x) \ | ||
87 | (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT) | ||
88 | #define PIN_SLPM_PULL_NONE \ | ||
89 | ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT) | ||
90 | #define PIN_SLPM_PULL_UP \ | ||
91 | ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT) | ||
92 | #define PIN_SLPM_PULL_DOWN \ | ||
93 | ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT) | ||
94 | |||
95 | #define PIN_SLPM_DIR_SHIFT 19 | ||
96 | #define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT) | ||
97 | #define PIN_SLPM_DIR(x) \ | ||
98 | (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT) | ||
99 | #define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT) | ||
100 | #define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT) | ||
101 | |||
102 | #define PIN_SLPM_VAL_SHIFT 21 | ||
103 | #define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT) | ||
104 | #define PIN_SLPM_VAL(x) \ | ||
105 | (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT) | ||
106 | #define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT) | ||
107 | #define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT) | ||
108 | |||
109 | /* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */ | ||
110 | #define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN) | ||
111 | #define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP) | ||
112 | #define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE) | ||
113 | #define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW) | ||
114 | #define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH) | ||
115 | |||
116 | #define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN) | ||
117 | #define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP) | ||
118 | #define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE) | ||
119 | #define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW) | ||
120 | #define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH) | ||
121 | |||
122 | #define PIN_CFG_DEFAULT (0) | ||
123 | |||
124 | #define PIN_CFG(num, alt) \ | ||
125 | (PIN_CFG_DEFAULT |\ | ||
126 | (PIN_NUM(num) | PIN_##alt)) | ||
127 | |||
128 | #define PIN_CFG_INPUT(num, alt, pull) \ | ||
129 | (PIN_CFG_DEFAULT |\ | ||
130 | (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull)) | ||
131 | |||
132 | #define PIN_CFG_OUTPUT(num, alt, val) \ | ||
133 | (PIN_CFG_DEFAULT |\ | ||
134 | (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val)) | ||
135 | |||
136 | #define PIN_CFG_PULL(num, alt, pull) \ | ||
137 | ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\ | ||
138 | (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull)) | ||
139 | |||
140 | extern int nmk_config_pin(pin_cfg_t cfg, bool sleep); | ||
141 | extern int nmk_config_pins(pin_cfg_t *cfgs, int num); | ||
142 | extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num); | ||
143 | |||
144 | #endif | ||
diff --git a/arch/arm/plat-nomadik/include/plat/ske.h b/arch/arm/plat-nomadik/include/plat/ske.h new file mode 100644 index 00000000000..31382fbc07d --- /dev/null +++ b/arch/arm/plat-nomadik/include/plat/ske.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * Author: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com> | ||
6 | * | ||
7 | * ux500 Scroll key and Keypad Encoder (SKE) header | ||
8 | */ | ||
9 | |||
10 | #ifndef __SKE_H | ||
11 | #define __SKE_H | ||
12 | |||
13 | #include <linux/input/matrix_keypad.h> | ||
14 | |||
15 | /* register definitions for SKE peripheral */ | ||
16 | #define SKE_CR 0x00 | ||
17 | #define SKE_VAL0 0x04 | ||
18 | #define SKE_VAL1 0x08 | ||
19 | #define SKE_DBCR 0x0C | ||
20 | #define SKE_IMSC 0x10 | ||
21 | #define SKE_RIS 0x14 | ||
22 | #define SKE_MIS 0x18 | ||
23 | #define SKE_ICR 0x1C | ||
24 | |||
25 | /* | ||
26 | * Keypad module | ||
27 | */ | ||
28 | |||
29 | /** | ||
30 | * struct keypad_platform_data - structure for platform specific data | ||
31 | * @init: pointer to keypad init function | ||
32 | * @exit: pointer to keypad deinitialisation function | ||
33 | * @keymap_data: matrix scan code table for keycodes | ||
34 | * @krow: maximum number of rows | ||
35 | * @kcol: maximum number of columns | ||
36 | * @debounce_ms: platform specific debounce time | ||
37 | * @no_autorepeat: flag for auto repetition | ||
38 | * @wakeup_enable: allow waking up the system | ||
39 | */ | ||
40 | struct ske_keypad_platform_data { | ||
41 | int (*init)(void); | ||
42 | int (*exit)(void); | ||
43 | const struct matrix_keymap_data *keymap_data; | ||
44 | u8 krow; | ||
45 | u8 kcol; | ||
46 | u8 debounce_ms; | ||
47 | bool no_autorepeat; | ||
48 | bool wakeup_enable; | ||
49 | }; | ||
50 | #endif /*__SKE_KPD_H*/ | ||
diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h new file mode 100644 index 00000000000..685c78716d9 --- /dev/null +++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h | |||
@@ -0,0 +1,219 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2007-2010 | ||
3 | * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson | ||
4 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | |||
8 | |||
9 | #ifndef STE_DMA40_H | ||
10 | #define STE_DMA40_H | ||
11 | |||
12 | #include <linux/dmaengine.h> | ||
13 | #include <linux/scatterlist.h> | ||
14 | #include <linux/workqueue.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | |||
17 | /* | ||
18 | * Maxium size for a single dma descriptor | ||
19 | * Size is limited to 16 bits. | ||
20 | * Size is in the units of addr-widths (1,2,4,8 bytes) | ||
21 | * Larger transfers will be split up to multiple linked desc | ||
22 | */ | ||
23 | #define STEDMA40_MAX_SEG_SIZE 0xFFFF | ||
24 | |||
25 | /* dev types for memcpy */ | ||
26 | #define STEDMA40_DEV_DST_MEMORY (-1) | ||
27 | #define STEDMA40_DEV_SRC_MEMORY (-1) | ||
28 | |||
29 | enum stedma40_mode { | ||
30 | STEDMA40_MODE_LOGICAL = 0, | ||
31 | STEDMA40_MODE_PHYSICAL, | ||
32 | STEDMA40_MODE_OPERATION, | ||
33 | }; | ||
34 | |||
35 | enum stedma40_mode_opt { | ||
36 | STEDMA40_PCHAN_BASIC_MODE = 0, | ||
37 | STEDMA40_LCHAN_SRC_LOG_DST_LOG = 0, | ||
38 | STEDMA40_PCHAN_MODULO_MODE, | ||
39 | STEDMA40_PCHAN_DOUBLE_DST_MODE, | ||
40 | STEDMA40_LCHAN_SRC_PHY_DST_LOG, | ||
41 | STEDMA40_LCHAN_SRC_LOG_DST_PHY, | ||
42 | }; | ||
43 | |||
44 | #define STEDMA40_ESIZE_8_BIT 0x0 | ||
45 | #define STEDMA40_ESIZE_16_BIT 0x1 | ||
46 | #define STEDMA40_ESIZE_32_BIT 0x2 | ||
47 | #define STEDMA40_ESIZE_64_BIT 0x3 | ||
48 | |||
49 | /* The value 4 indicates that PEN-reg shall be set to 0 */ | ||
50 | #define STEDMA40_PSIZE_PHY_1 0x4 | ||
51 | #define STEDMA40_PSIZE_PHY_2 0x0 | ||
52 | #define STEDMA40_PSIZE_PHY_4 0x1 | ||
53 | #define STEDMA40_PSIZE_PHY_8 0x2 | ||
54 | #define STEDMA40_PSIZE_PHY_16 0x3 | ||
55 | |||
56 | /* | ||
57 | * The number of elements differ in logical and | ||
58 | * physical mode | ||
59 | */ | ||
60 | #define STEDMA40_PSIZE_LOG_1 STEDMA40_PSIZE_PHY_2 | ||
61 | #define STEDMA40_PSIZE_LOG_4 STEDMA40_PSIZE_PHY_4 | ||
62 | #define STEDMA40_PSIZE_LOG_8 STEDMA40_PSIZE_PHY_8 | ||
63 | #define STEDMA40_PSIZE_LOG_16 STEDMA40_PSIZE_PHY_16 | ||
64 | |||
65 | /* Maximum number of possible physical channels */ | ||
66 | #define STEDMA40_MAX_PHYS 32 | ||
67 | |||
68 | enum stedma40_flow_ctrl { | ||
69 | STEDMA40_NO_FLOW_CTRL, | ||
70 | STEDMA40_FLOW_CTRL, | ||
71 | }; | ||
72 | |||
73 | enum stedma40_periph_data_width { | ||
74 | STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT, | ||
75 | STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT, | ||
76 | STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT, | ||
77 | STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT | ||
78 | }; | ||
79 | |||
80 | enum stedma40_xfer_dir { | ||
81 | STEDMA40_MEM_TO_MEM = 1, | ||
82 | STEDMA40_MEM_TO_PERIPH, | ||
83 | STEDMA40_PERIPH_TO_MEM, | ||
84 | STEDMA40_PERIPH_TO_PERIPH | ||
85 | }; | ||
86 | |||
87 | |||
88 | /** | ||
89 | * struct stedma40_chan_cfg - dst/src channel configuration | ||
90 | * | ||
91 | * @big_endian: true if the src/dst should be read as big endian | ||
92 | * @data_width: Data width of the src/dst hardware | ||
93 | * @p_size: Burst size | ||
94 | * @flow_ctrl: Flow control on/off. | ||
95 | */ | ||
96 | struct stedma40_half_channel_info { | ||
97 | bool big_endian; | ||
98 | enum stedma40_periph_data_width data_width; | ||
99 | int psize; | ||
100 | enum stedma40_flow_ctrl flow_ctrl; | ||
101 | }; | ||
102 | |||
103 | /** | ||
104 | * struct stedma40_chan_cfg - Structure to be filled by client drivers. | ||
105 | * | ||
106 | * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH | ||
107 | * @high_priority: true if high-priority | ||
108 | * @realtime: true if realtime mode is to be enabled. Only available on DMA40 | ||
109 | * version 3+, i.e DB8500v2+ | ||
110 | * @mode: channel mode: physical, logical, or operation | ||
111 | * @mode_opt: options for the chosen channel mode | ||
112 | * @src_dev_type: Src device type | ||
113 | * @dst_dev_type: Dst device type | ||
114 | * @src_info: Parameters for dst half channel | ||
115 | * @dst_info: Parameters for dst half channel | ||
116 | * | ||
117 | * | ||
118 | * This structure has to be filled by the client drivers. | ||
119 | * It is recommended to do all dma configurations for clients in the machine. | ||
120 | * | ||
121 | */ | ||
122 | struct stedma40_chan_cfg { | ||
123 | enum stedma40_xfer_dir dir; | ||
124 | bool high_priority; | ||
125 | bool realtime; | ||
126 | enum stedma40_mode mode; | ||
127 | enum stedma40_mode_opt mode_opt; | ||
128 | int src_dev_type; | ||
129 | int dst_dev_type; | ||
130 | struct stedma40_half_channel_info src_info; | ||
131 | struct stedma40_half_channel_info dst_info; | ||
132 | }; | ||
133 | |||
134 | /** | ||
135 | * struct stedma40_platform_data - Configuration struct for the dma device. | ||
136 | * | ||
137 | * @dev_len: length of dev_tx and dev_rx | ||
138 | * @dev_tx: mapping between destination event line and io address | ||
139 | * @dev_rx: mapping between source event line and io address | ||
140 | * @memcpy: list of memcpy event lines | ||
141 | * @memcpy_len: length of memcpy | ||
142 | * @memcpy_conf_phy: default configuration of physical channel memcpy | ||
143 | * @memcpy_conf_log: default configuration of logical channel memcpy | ||
144 | * @disabled_channels: A vector, ending with -1, that marks physical channels | ||
145 | * that are for different reasons not available for the driver. | ||
146 | */ | ||
147 | struct stedma40_platform_data { | ||
148 | u32 dev_len; | ||
149 | const dma_addr_t *dev_tx; | ||
150 | const dma_addr_t *dev_rx; | ||
151 | int *memcpy; | ||
152 | u32 memcpy_len; | ||
153 | struct stedma40_chan_cfg *memcpy_conf_phy; | ||
154 | struct stedma40_chan_cfg *memcpy_conf_log; | ||
155 | int disabled_channels[STEDMA40_MAX_PHYS]; | ||
156 | }; | ||
157 | |||
158 | #ifdef CONFIG_STE_DMA40 | ||
159 | |||
160 | /** | ||
161 | * stedma40_filter() - Provides stedma40_chan_cfg to the | ||
162 | * ste_dma40 dma driver via the dmaengine framework. | ||
163 | * does some checking of what's provided. | ||
164 | * | ||
165 | * Never directly called by client. It used by dmaengine. | ||
166 | * @chan: dmaengine handle. | ||
167 | * @data: Must be of type: struct stedma40_chan_cfg and is | ||
168 | * the configuration of the framework. | ||
169 | * | ||
170 | * | ||
171 | */ | ||
172 | |||
173 | bool stedma40_filter(struct dma_chan *chan, void *data); | ||
174 | |||
175 | /** | ||
176 | * stedma40_slave_mem() - Transfers a raw data buffer to or from a slave | ||
177 | * (=device) | ||
178 | * | ||
179 | * @chan: dmaengine handle | ||
180 | * @addr: source or destination physicall address. | ||
181 | * @size: bytes to transfer | ||
182 | * @direction: direction of transfer | ||
183 | * @flags: is actually enum dma_ctrl_flags. See dmaengine.h | ||
184 | */ | ||
185 | |||
186 | static inline struct | ||
187 | dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, | ||
188 | dma_addr_t addr, | ||
189 | unsigned int size, | ||
190 | enum dma_data_direction direction, | ||
191 | unsigned long flags) | ||
192 | { | ||
193 | struct scatterlist sg; | ||
194 | sg_init_table(&sg, 1); | ||
195 | sg.dma_address = addr; | ||
196 | sg.length = size; | ||
197 | |||
198 | return chan->device->device_prep_slave_sg(chan, &sg, 1, | ||
199 | direction, flags); | ||
200 | } | ||
201 | |||
202 | #else | ||
203 | static inline bool stedma40_filter(struct dma_chan *chan, void *data) | ||
204 | { | ||
205 | return false; | ||
206 | } | ||
207 | |||
208 | static inline struct | ||
209 | dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, | ||
210 | dma_addr_t addr, | ||
211 | unsigned int size, | ||
212 | enum dma_data_direction direction, | ||
213 | unsigned long flags) | ||
214 | { | ||
215 | return NULL; | ||
216 | } | ||
217 | #endif | ||
218 | |||
219 | #endif | ||
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c new file mode 100644 index 00000000000..ef74e157a9d --- /dev/null +++ b/arch/arm/plat-nomadik/timer.c | |||
@@ -0,0 +1,174 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/plat-nomadik/timer.c | ||
3 | * | ||
4 | * Copyright (C) 2008 STMicroelectronics | ||
5 | * Copyright (C) 2010 Alessandro Rubini | ||
6 | * Copyright (C) 2010 Linus Walleij for ST-Ericsson | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2, as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/clockchips.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/jiffies.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include <asm/mach/time.h> | ||
22 | #include <asm/sched_clock.h> | ||
23 | |||
24 | #include <plat/mtu.h> | ||
25 | |||
26 | void __iomem *mtu_base; /* Assigned by machine code */ | ||
27 | |||
28 | /* | ||
29 | * Override the global weak sched_clock symbol with this | ||
30 | * local implementation which uses the clocksource to get some | ||
31 | * better resolution when scheduling the kernel. | ||
32 | */ | ||
33 | static DEFINE_CLOCK_DATA(cd); | ||
34 | |||
35 | unsigned long long notrace sched_clock(void) | ||
36 | { | ||
37 | u32 cyc; | ||
38 | |||
39 | if (unlikely(!mtu_base)) | ||
40 | return 0; | ||
41 | |||
42 | cyc = -readl(mtu_base + MTU_VAL(0)); | ||
43 | return cyc_to_sched_clock(&cd, cyc, (u32)~0); | ||
44 | } | ||
45 | |||
46 | static void notrace nomadik_update_sched_clock(void) | ||
47 | { | ||
48 | u32 cyc = -readl(mtu_base + MTU_VAL(0)); | ||
49 | update_sched_clock(&cd, cyc, (u32)~0); | ||
50 | } | ||
51 | |||
52 | /* Clockevent device: use one-shot mode */ | ||
53 | static void nmdk_clkevt_mode(enum clock_event_mode mode, | ||
54 | struct clock_event_device *dev) | ||
55 | { | ||
56 | u32 cr; | ||
57 | |||
58 | switch (mode) { | ||
59 | case CLOCK_EVT_MODE_PERIODIC: | ||
60 | pr_err("%s: periodic mode not supported\n", __func__); | ||
61 | break; | ||
62 | case CLOCK_EVT_MODE_ONESHOT: | ||
63 | /* Load highest value, enable device, enable interrupts */ | ||
64 | cr = readl(mtu_base + MTU_CR(1)); | ||
65 | writel(0, mtu_base + MTU_LR(1)); | ||
66 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); | ||
67 | writel(1 << 1, mtu_base + MTU_IMSC); | ||
68 | break; | ||
69 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
70 | case CLOCK_EVT_MODE_UNUSED: | ||
71 | /* disable irq */ | ||
72 | writel(0, mtu_base + MTU_IMSC); | ||
73 | /* disable timer */ | ||
74 | cr = readl(mtu_base + MTU_CR(1)); | ||
75 | cr &= ~MTU_CRn_ENA; | ||
76 | writel(cr, mtu_base + MTU_CR(1)); | ||
77 | /* load some high default value */ | ||
78 | writel(0xffffffff, mtu_base + MTU_LR(1)); | ||
79 | break; | ||
80 | case CLOCK_EVT_MODE_RESUME: | ||
81 | break; | ||
82 | } | ||
83 | } | ||
84 | |||
85 | static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev) | ||
86 | { | ||
87 | /* writing the value has immediate effect */ | ||
88 | writel(evt, mtu_base + MTU_LR(1)); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static struct clock_event_device nmdk_clkevt = { | ||
93 | .name = "mtu_1", | ||
94 | .features = CLOCK_EVT_FEAT_ONESHOT, | ||
95 | .rating = 200, | ||
96 | .set_mode = nmdk_clkevt_mode, | ||
97 | .set_next_event = nmdk_clkevt_next, | ||
98 | }; | ||
99 | |||
100 | /* | ||
101 | * IRQ Handler for timer 1 of the MTU block. | ||
102 | */ | ||
103 | static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id) | ||
104 | { | ||
105 | struct clock_event_device *evdev = dev_id; | ||
106 | |||
107 | writel(1 << 1, mtu_base + MTU_ICR); /* Interrupt clear reg */ | ||
108 | evdev->event_handler(evdev); | ||
109 | return IRQ_HANDLED; | ||
110 | } | ||
111 | |||
112 | static struct irqaction nmdk_timer_irq = { | ||
113 | .name = "Nomadik Timer Tick", | ||
114 | .flags = IRQF_DISABLED | IRQF_TIMER, | ||
115 | .handler = nmdk_timer_interrupt, | ||
116 | .dev_id = &nmdk_clkevt, | ||
117 | }; | ||
118 | |||
119 | void __init nmdk_timer_init(void) | ||
120 | { | ||
121 | unsigned long rate; | ||
122 | struct clk *clk0; | ||
123 | u32 cr = MTU_CRn_32BITS; | ||
124 | |||
125 | clk0 = clk_get_sys("mtu0", NULL); | ||
126 | BUG_ON(IS_ERR(clk0)); | ||
127 | |||
128 | clk_enable(clk0); | ||
129 | |||
130 | /* | ||
131 | * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz | ||
132 | * for ux500. | ||
133 | * Use a divide-by-16 counter if the tick rate is more than 32MHz. | ||
134 | * At 32 MHz, the timer (with 32 bit counter) can be programmed | ||
135 | * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer | ||
136 | * with 16 gives too low timer resolution. | ||
137 | */ | ||
138 | rate = clk_get_rate(clk0); | ||
139 | if (rate > 32000000) { | ||
140 | rate /= 16; | ||
141 | cr |= MTU_CRn_PRESCALE_16; | ||
142 | } else { | ||
143 | cr |= MTU_CRn_PRESCALE_1; | ||
144 | } | ||
145 | |||
146 | /* Timer 0 is the free running clocksource */ | ||
147 | writel(cr, mtu_base + MTU_CR(0)); | ||
148 | writel(0, mtu_base + MTU_LR(0)); | ||
149 | writel(0, mtu_base + MTU_BGLR(0)); | ||
150 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); | ||
151 | |||
152 | if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0", | ||
153 | rate, 200, 32, clocksource_mmio_readl_down)) | ||
154 | pr_err("timer: failed to initialize clock source %s\n", | ||
155 | "mtu_0"); | ||
156 | |||
157 | init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate); | ||
158 | |||
159 | /* Timer 1 is used for events */ | ||
160 | |||
161 | clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); | ||
162 | |||
163 | writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ | ||
164 | |||
165 | nmdk_clkevt.max_delta_ns = | ||
166 | clockevent_delta2ns(0xffffffff, &nmdk_clkevt); | ||
167 | nmdk_clkevt.min_delta_ns = | ||
168 | clockevent_delta2ns(0x00000002, &nmdk_clkevt); | ||
169 | nmdk_clkevt.cpumask = cpumask_of(0); | ||
170 | |||
171 | /* Register irq and clockevents */ | ||
172 | setup_irq(IRQ_MTU0, &nmdk_timer_irq); | ||
173 | clockevents_register_device(&nmdk_clkevt); | ||
174 | } | ||