aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-nomadik
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/plat-nomadik
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'arch/arm/plat-nomadik')
-rw-r--r--arch/arm/plat-nomadik/Kconfig24
-rw-r--r--arch/arm/plat-nomadik/Makefile5
-rw-r--r--arch/arm/plat-nomadik/include/plat/gpio.h96
-rw-r--r--arch/arm/plat-nomadik/include/plat/i2c.h39
-rw-r--r--arch/arm/plat-nomadik/include/plat/mtu.h54
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h144
-rw-r--r--arch/arm/plat-nomadik/include/plat/ske.h50
-rw-r--r--arch/arm/plat-nomadik/include/plat/ste_dma40.h219
-rw-r--r--arch/arm/plat-nomadik/timer.c174
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
5config 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
14if PLAT_NOMADIK
15
16config 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
24endif
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
5obj-$(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 */
59enum nmk_gpio_pull {
60 NMK_GPIO_PULL_NONE,
61 NMK_GPIO_PULL_UP,
62 NMK_GPIO_PULL_DOWN,
63};
64
65/* Sleep mode */
66enum 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
73extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
74extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull);
75extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
76extern int nmk_gpio_get_mode(int gpio);
77
78extern void nmk_gpio_wakeups_suspend(void);
79extern void nmk_gpio_wakeups_resume(void);
80
81extern 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 */
86struct 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
11enum 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 */
30struct 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 */
11extern 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
43typedef 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
140extern int nmk_config_pin(pin_cfg_t cfg, bool sleep);
141extern int nmk_config_pins(pin_cfg_t *cfgs, int num);
142extern 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 */
40struct 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
29enum stedma40_mode {
30 STEDMA40_MODE_LOGICAL = 0,
31 STEDMA40_MODE_PHYSICAL,
32 STEDMA40_MODE_OPERATION,
33};
34
35enum 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
68enum stedma40_flow_ctrl {
69 STEDMA40_NO_FLOW_CTRL,
70 STEDMA40_FLOW_CTRL,
71};
72
73enum 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
80enum 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 */
96struct 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 */
122struct 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 */
147struct 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
173bool 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
186static inline struct
187dma_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
203static inline bool stedma40_filter(struct dma_chan *chan, void *data)
204{
205 return false;
206}
207
208static inline struct
209dma_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
26void __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 */
33static DEFINE_CLOCK_DATA(cd);
34
35unsigned 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
46static 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 */
53static 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
85static 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
92static 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 */
103static 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
112static 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
119void __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}