1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
/*
* Atmel SMC (Static Memory Controller) register offsets and bit definitions.
*
* Copyright (C) 2014 Atmel
* Copyright (C) 2014 Free Electrons
*
* Author: Boris Brezillon <boris.brezillon@free-electrons.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _LINUX_MFD_SYSCON_ATMEL_SMC_H_
#define _LINUX_MFD_SYSCON_ATMEL_SMC_H_
#include <linux/kernel.h>
#include <linux/regmap.h>
#define AT91SAM9_SMC_GENERIC 0x00
#define AT91SAM9_SMC_GENERIC_BLK_SZ 0x10
#define SAMA5_SMC_GENERIC 0x600
#define SAMA5_SMC_GENERIC_BLK_SZ 0x14
#define AT91SAM9_SMC_SETUP(o) ((o) + 0x00)
#define AT91SAM9_SMC_NWESETUP(x) (x)
#define AT91SAM9_SMC_NCS_WRSETUP(x) ((x) << 8)
#define AT91SAM9_SMC_NRDSETUP(x) ((x) << 16)
#define AT91SAM9_SMC_NCS_NRDSETUP(x) ((x) << 24)
#define AT91SAM9_SMC_PULSE(o) ((o) + 0x04)
#define AT91SAM9_SMC_NWEPULSE(x) (x)
#define AT91SAM9_SMC_NCS_WRPULSE(x) ((x) << 8)
#define AT91SAM9_SMC_NRDPULSE(x) ((x) << 16)
#define AT91SAM9_SMC_NCS_NRDPULSE(x) ((x) << 24)
#define AT91SAM9_SMC_CYCLE(o) ((o) + 0x08)
#define AT91SAM9_SMC_NWECYCLE(x) (x)
#define AT91SAM9_SMC_NRDCYCLE(x) ((x) << 16)
#define AT91SAM9_SMC_MODE(o) ((o) + 0x0c)
#define SAMA5_SMC_MODE(o) ((o) + 0x10)
#define AT91_SMC_READMODE BIT(0)
#define AT91_SMC_READMODE_NCS (0 << 0)
#define AT91_SMC_READMODE_NRD (1 << 0)
#define AT91_SMC_WRITEMODE BIT(1)
#define AT91_SMC_WRITEMODE_NCS (0 << 1)
#define AT91_SMC_WRITEMODE_NWE (1 << 1)
#define AT91_SMC_EXNWMODE GENMASK(5, 4)
#define AT91_SMC_EXNWMODE_DISABLE (0 << 4)
#define AT91_SMC_EXNWMODE_FROZEN (2 << 4)
#define AT91_SMC_EXNWMODE_READY (3 << 4)
#define AT91_SMC_BAT BIT(8)
#define AT91_SMC_BAT_SELECT (0 << 8)
#define AT91_SMC_BAT_WRITE (1 << 8)
#define AT91_SMC_DBW GENMASK(13, 12)
#define AT91_SMC_DBW_8 (0 << 12)
#define AT91_SMC_DBW_16 (1 << 12)
#define AT91_SMC_DBW_32 (2 << 12)
#define AT91_SMC_TDF GENMASK(19, 16)
#define AT91_SMC_TDF_(x) ((((x) - 1) << 16) & AT91_SMC_TDF)
#define AT91_SMC_TDF_MAX 16
#define AT91_SMC_TDFMODE_OPTIMIZED BIT(20)
#define AT91_SMC_PMEN BIT(24)
#define AT91_SMC_PS GENMASK(29, 28)
#define AT91_SMC_PS_4 (0 << 28)
#define AT91_SMC_PS_8 (1 << 28)
#define AT91_SMC_PS_16 (2 << 28)
#define AT91_SMC_PS_32 (3 << 28)
/*
* This function converts a setup timing expressed in nanoseconds into an
* encoded value that can be written in the SMC_SETUP register.
*
* The following formula is described in atmel datasheets (section
* "SMC Setup Register"):
*
* setup length = (128* SETUP[5] + SETUP[4:0])
*
* where setup length is the timing expressed in cycles.
*/
static inline u32 at91sam9_smc_setup_ns_to_cycles(unsigned int clk_rate,
u32 timing_ns)
{
u32 clk_period = DIV_ROUND_UP(NSEC_PER_SEC, clk_rate);
u32 coded_cycles = 0;
u32 cycles;
cycles = DIV_ROUND_UP(timing_ns, clk_period);
if (cycles / 32) {
coded_cycles |= 1 << 5;
if (cycles < 128)
cycles = 0;
}
coded_cycles |= cycles % 32;
return coded_cycles;
}
/*
* This function converts a pulse timing expressed in nanoseconds into an
* encoded value that can be written in the SMC_PULSE register.
*
* The following formula is described in atmel datasheets (section
* "SMC Pulse Register"):
*
* pulse length = (256* PULSE[6] + PULSE[5:0])
*
* where pulse length is the timing expressed in cycles.
*/
static inline u32 at91sam9_smc_pulse_ns_to_cycles(unsigned int clk_rate,
u32 timing_ns)
{
u32 clk_period = DIV_ROUND_UP(NSEC_PER_SEC, clk_rate);
u32 coded_cycles = 0;
u32 cycles;
cycles = DIV_ROUND_UP(timing_ns, clk_period);
if (cycles / 64) {
coded_cycles |= 1 << 6;
if (cycles < 256)
cycles = 0;
}
coded_cycles |= cycles % 64;
return coded_cycles;
}
/*
* This function converts a cycle timing expressed in nanoseconds into an
* encoded value that can be written in the SMC_CYCLE register.
*
* The following formula is described in atmel datasheets (section
* "SMC Cycle Register"):
*
* cycle length = (CYCLE[8:7]*256 + CYCLE[6:0])
*
* where cycle length is the timing expressed in cycles.
*/
static inline u32 at91sam9_smc_cycle_ns_to_cycles(unsigned int clk_rate,
u32 timing_ns)
{
u32 clk_period = DIV_ROUND_UP(NSEC_PER_SEC, clk_rate);
u32 coded_cycles = 0;
u32 cycles;
cycles = DIV_ROUND_UP(timing_ns, clk_period);
if (cycles / 128) {
coded_cycles = cycles / 256;
cycles %= 256;
if (cycles >= 128) {
coded_cycles++;
cycles = 0;
}
if (coded_cycles > 0x3) {
coded_cycles = 0x3;
cycles = 0x7f;
}
coded_cycles <<= 7;
}
coded_cycles |= cycles % 128;
return coded_cycles;
}
#endif /* _LINUX_MFD_SYSCON_ATMEL_SMC_H_ */
|