12
12
#include <zephyr/pm/device.h>
13
13
#include <zephyr/pm/policy.h>
14
14
#include <zephyr/pm/device_runtime.h>
15
-
16
- #include <soc.h>
17
-
18
- #include <zephyr/mem_mgmt/mem_attr.h>
19
-
20
- #ifdef CONFIG_DCACHE
21
- #include <zephyr/dt-bindings/memory-attr/memory-attr-arm.h>
22
- #endif /* CONFIG_DCACHE */
23
-
24
- #ifdef CONFIG_NOCACHE_MEMORY
25
- #include <zephyr/linker/linker-defs.h>
26
- #elif defined(CONFIG_CACHE_MANAGEMENT )
27
- #include <zephyr/arch/cache.h>
28
- #endif /* CONFIG_NOCACHE_MEMORY */
29
-
30
- #if defined(CONFIG_DCACHE ) && !defined(CONFIG_NOCACHE_MEMORY )
31
- #define I2C_AMBIQ_MANUAL_CACHE_COHERENCY_REQUIRED 1
32
- #else
33
- #define I2C_AMBIQ_MANUAL_CACHE_COHERENCY_REQUIRED 0
34
- #endif /* defined(CONFIG_DCACHE) && !defined(CONFIG_NOCACHE_MEMORY) */
15
+ #include <zephyr/cache.h>
35
16
36
17
#ifdef CONFIG_I2C_AMBIQ_BUS_RECOVERY
37
18
#include <zephyr/drivers/gpio.h>
@@ -47,6 +28,8 @@ LOG_MODULE_REGISTER(ambiq_i2c, CONFIG_I2C_LOG_LEVEL);
47
28
48
29
#include "i2c-priv.h"
49
30
31
+ #include <soc.h>
32
+
50
33
struct i2c_ambiq_config {
51
34
#ifdef CONFIG_I2C_AMBIQ_BUS_RECOVERY
52
35
struct gpio_dt_spec scl ;
@@ -100,16 +83,6 @@ static void i2c_ambiq_pm_policy_state_lock_put(const struct device *dev)
100
83
}
101
84
102
85
#ifdef CONFIG_I2C_AMBIQ_DMA
103
- /*
104
- * If Nocache Memory is supported, buffer will be placed in nocache region by
105
- * the linker to avoid potential DMA cache-coherency problems.
106
- * If Nocache Memory is not supported, cache coherency might need to be kept
107
- * manually. See I2C_AMBIQ_MANUAL_CACHE_COHERENCY_REQUIRED.
108
- */
109
- static __aligned (32 ) struct {
110
- __aligned (32 ) uint32_t buf [CONFIG_I2C_DMA_TCB_BUFFER_SIZE ];
111
- } i2c_dma_tcb_buf [DT_NUM_INST_STATUS_OKAY (DT_DRV_COMPAT )] __nocache ;
112
-
113
86
static void i2c_ambiq_callback (void * callback_ctxt , uint32_t status )
114
87
{
115
88
const struct device * dev = callback_ctxt ;
@@ -120,39 +93,6 @@ static void i2c_ambiq_callback(void *callback_ctxt, uint32_t status)
120
93
}
121
94
data -> transfer_status = status ;
122
95
}
123
-
124
- #ifdef CONFIG_DCACHE
125
- static bool buf_in_nocache (uintptr_t buf , size_t len_bytes )
126
- {
127
- bool buf_within_nocache = false;
128
-
129
- #ifdef CONFIG_NOCACHE_MEMORY
130
- /* Check if buffer is in nocache region defined by the linker */
131
- buf_within_nocache = (buf >= ((uintptr_t )_nocache_ram_start )) &&
132
- ((buf + len_bytes - 1 ) <= ((uintptr_t )_nocache_ram_end ));
133
- if (buf_within_nocache ) {
134
- return true;
135
- }
136
- #endif /* CONFIG_NOCACHE_MEMORY */
137
-
138
- /* Check if buffer is in nocache memory region defined in DT */
139
- buf_within_nocache =
140
- mem_attr_check_buf ((void * )buf , len_bytes , DT_MEM_ARM (ATTR_MPU_RAM_NOCACHE )) == 0 ;
141
-
142
- return buf_within_nocache ;
143
- }
144
-
145
- static bool i2c_buf_set_in_nocache (const struct i2c_msg * msgs , uint8_t num_msgs )
146
- {
147
- for (int i = 0 ; i < num_msgs ; i ++ ) {
148
- if (!buf_in_nocache ((uintptr_t )msgs [i ]-> buf , msgs [i ]-> len )) {
149
- return false;
150
- }
151
- }
152
- return true;
153
- }
154
- #endif /* CONFIG_DCACHE */
155
-
156
96
#endif
157
97
158
98
static void i2c_ambiq_isr (const struct device * dev )
@@ -205,10 +145,12 @@ static int i2c_ambiq_read(const struct device *dev, struct i2c_msg *hdr_msg,
205
145
am_hal_iom_enable (data -> iom_handler );
206
146
return - ETIMEDOUT ;
207
147
}
208
- #if I2C_AMBIQ_MANUAL_CACHE_COHERENCY_REQUIRED
209
- /* Invalidate Dcache after DMA read */
210
- sys_cache_data_invd_range ((void * )trans .pui32RxBuffer , trans .ui32NumBytes );
211
- #endif /* I2C_AMBIQ_MANUAL_CACHE_COHERENCY_REQUIRED */
148
+ #if CONFIG_I2C_AMBIQ_HANDLE_CACHE
149
+ if (!buf_in_nocache ((uintptr_t )trans .pui32RxBuffer , trans .ui32NumBytes )) {
150
+ /* Invalidate Dcache after DMA read */
151
+ sys_cache_data_invd_range ((void * )trans .pui32RxBuffer , trans .ui32NumBytes );
152
+ }
153
+ #endif /* CONFIG_I2C_AMBIQ_HANDLE_CACHE */
212
154
ret = data -> transfer_status ;
213
155
#else
214
156
ret = am_hal_iom_blocking_transfer (data -> iom_handler , & trans );
@@ -244,10 +186,12 @@ static int i2c_ambiq_write(const struct device *dev, struct i2c_msg *hdr_msg,
244
186
245
187
#ifdef CONFIG_I2C_AMBIQ_DMA
246
188
data -> transfer_status = - EFAULT ;
247
- #if I2C_AMBIQ_MANUAL_CACHE_COHERENCY_REQUIRED
248
- /* Clean Dcache before DMA write */
249
- sys_cache_data_flush_range ((void * )trans .pui32TxBuffer , trans .ui32NumBytes );
250
- #endif /* I2C_AMBIQ_MANUAL_CACHE_COHERENCY_REQUIRED */
189
+ #if CONFIG_I2C_AMBIQ_HANDLE_CACHE
190
+ if (!buf_in_nocache ((uintptr_t )trans .pui32TxBuffer , trans .ui32NumBytes )) {
191
+ /* Clean Dcache before DMA write */
192
+ sys_cache_data_flush_range ((void * )trans .pui32TxBuffer , trans .ui32NumBytes );
193
+ }
194
+ #endif /* CONFIG_I2C_AMBIQ_HANDLE_CACHE */
251
195
ret = am_hal_iom_nonblocking_transfer (data -> iom_handler , & trans , i2c_ambiq_callback ,
252
196
(void * )dev );
253
197
@@ -290,13 +234,6 @@ static int i2c_ambiq_configure(const struct device *dev, uint32_t dev_config)
290
234
return - EINVAL ;
291
235
}
292
236
293
- #ifdef CONFIG_I2C_AMBIQ_DMA
294
- const struct i2c_ambiq_config * cfg = dev -> config ;
295
-
296
- data -> iom_cfg .pNBTxnBuf = i2c_dma_tcb_buf [cfg -> inst_idx ].buf ;
297
- data -> iom_cfg .ui32NBTxnBufLength = CONFIG_I2C_DMA_TCB_BUFFER_SIZE ;
298
- #endif
299
-
300
237
am_hal_iom_configure (data -> iom_handler , & data -> iom_cfg );
301
238
302
239
return 0 ;
@@ -312,12 +249,6 @@ static int i2c_ambiq_transfer(const struct device *dev, struct i2c_msg *msgs, ui
312
249
return 0 ;
313
250
}
314
251
315
- #if defined(CONFIG_I2C_AMBIQ_DMA ) && defined(CONFIG_DCACHE )
316
- if (!i2c_buf_set_in_nocache (msgs , num_msgs )) {
317
- return - EFAULT ;
318
- }
319
- #endif /* CONFIG_DCACHE */
320
-
321
252
i2c_ambiq_pm_policy_state_lock_get (dev );
322
253
323
254
/* Send out messages */
@@ -441,8 +372,6 @@ static int i2c_ambiq_init(const struct device *dev)
441
372
uint32_t bitrate_cfg = i2c_map_dt_bitrate (config -> bitrate );
442
373
int ret = 0 ;
443
374
444
- data -> iom_cfg .eInterfaceMode = AM_HAL_IOM_I2C_MODE ;
445
-
446
375
if (AM_HAL_STATUS_SUCCESS != am_hal_iom_initialize (config -> inst_idx , & data -> iom_handler )) {
447
376
LOG_ERR ("Fail to initialize I2C\n" );
448
377
return - ENXIO ;
@@ -518,17 +447,38 @@ static int i2c_ambiq_pm_action(const struct device *dev, enum pm_device_action a
518
447
}
519
448
#endif /* CONFIG_PM_DEVICE */
520
449
450
+ #define IOM_HAL_CFG (n , cmdq , cmdq_size ) \
451
+ { \
452
+ .eInterfaceMode = AM_HAL_IOM_I2C_MODE, \
453
+ .ui32ClockFreq = AM_HAL_IOM_100KHZ, \
454
+ .pNBTxnBuf = cmdq, \
455
+ .ui32NBTxnBufLength = cmdq_size, \
456
+ }
457
+
521
458
#define AMBIQ_I2C_DEFINE (n ) \
459
+ BUILD_ASSERT(DT_CHILD_NUM_STATUS_OKAY(DT_INST_PARENT(n)) == 1, \
460
+ "Too many children for IOM, either SPI or I2C should be enabled!"); \
522
461
PINCTRL_DT_INST_DEFINE(n); \
523
462
static void i2c_irq_config_func_##n(void) \
524
463
{ \
525
464
IRQ_CONNECT(DT_IRQN(DT_INST_PARENT(n)), DT_IRQ(DT_INST_PARENT(n), priority), \
526
465
i2c_ambiq_isr, DEVICE_DT_INST_GET(n), 0); \
527
466
irq_enable(DT_IRQN(DT_INST_PARENT(n))); \
528
467
}; \
468
+ IF_ENABLED(CONFIG_I2C_AMBIQ_DMA, \
469
+ (static uint32_t i2c_ambiq_cmdq##n[DT_PROP_OR(DT_INST_PARENT(n), cmdq_buffer_size, 1024)] \
470
+ __attribute__((section(DT_PROP_OR(DT_INST_PARENT(n), \
471
+ cmdq_buffer_location, ".nocache"))));) \
472
+ ) \
529
473
static struct i2c_ambiq_data i2c_ambiq_data##n = { \
474
+ .iom_cfg = IOM_HAL_CFG(n, COND_CODE_1(CONFIG_I2C_AMBIQ_DMA, (i2c_ambiq_cmdq##n), \
475
+ (NULL)), \
476
+ COND_CODE_1(CONFIG_I2C_AMBIQ_DMA, \
477
+ (DT_INST_PROP_OR(n, cmdq_buffer_size, 1024)), (0)) \
478
+ ), \
530
479
.bus_sem = Z_SEM_INITIALIZER(i2c_ambiq_data##n.bus_sem, 1, 1), \
531
- .transfer_sem = Z_SEM_INITIALIZER(i2c_ambiq_data##n.transfer_sem, 0, 1)}; \
480
+ .transfer_sem = Z_SEM_INITIALIZER(i2c_ambiq_data##n.transfer_sem, 0, 1), \
481
+ }; \
532
482
static const struct i2c_ambiq_config i2c_ambiq_config##n = { \
533
483
.base = DT_REG_ADDR(DT_INST_PARENT(n)), \
534
484
.size = DT_REG_SIZE(DT_INST_PARENT(n)), \
0 commit comments