Skip to content

Commit eab1cab

Browse files
tlaudalgirdwood
authored andcommitted
mn: add M/N dividers to sof context
Adds pointer to mn struct to sof context. Also implements getter, so it can be retrieved through one point of access. Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
1 parent bd6467b commit eab1cab

4 files changed

Lines changed: 70 additions & 35 deletions

File tree

src/drivers/intel/cavs/mn.c

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <sof/drivers/ssp.h>
99
#include <sof/lib/shim.h>
1010
#include <sof/math/numbers.h>
11+
#include <sof/sof.h>
1112
#include <sof/spinlock.h>
1213
#include <sof/trace/trace.h>
1314
#include <stdbool.h>
@@ -53,14 +54,16 @@ struct mn {
5354

5455
struct mn mn;
5556

56-
void mn_init(void)
57+
void mn_init(struct sof *sof)
5758
{
5859
int i;
5960

60-
for (i = 0; i < ARRAY_SIZE(mn.bclk_sources); i++)
61-
mn.bclk_sources[i] = MN_BCLK_SOURCE_NONE;
61+
sof->mn = &mn;
6262

63-
spinlock_init(&mn.lock);
63+
for (i = 0; i < ARRAY_SIZE(sof->mn->bclk_sources); i++)
64+
sof->mn->bclk_sources[i] = MN_BCLK_SOURCE_NONE;
65+
66+
spinlock_init(&sof->mn->lock);
6467
}
6568

6669
/**
@@ -70,10 +73,11 @@ void mn_init(void)
7073
*/
7174
static inline bool is_mclk_source_in_use(void)
7275
{
76+
struct mn *mn = mn_get();
7377
int i;
7478

75-
for (i = 0; i < ARRAY_SIZE(mn.mclk_sources_used); i++)
76-
if (mn.mclk_sources_used[i])
79+
for (i = 0; i < ARRAY_SIZE(mn->mclk_sources_used); i++)
80+
if (mn->mclk_sources_used[i])
7781
return true;
7882
return false;
7983
}
@@ -87,6 +91,7 @@ static inline bool is_mclk_source_in_use(void)
8791
*/
8892
static inline int setup_initial_mclk_source(uint32_t mclk_rate)
8993
{
94+
struct mn *mn = mn_get();
9095
int i;
9196
int clk_index = -1;
9297
uint32_t mdivc = mn_reg_read(MN_MDIVCTRL);
@@ -106,7 +111,7 @@ static inline int setup_initial_mclk_source(uint32_t mclk_rate)
106111
return -EINVAL;
107112
}
108113

109-
mn.mclk_source_clock = clk_index;
114+
mn->mclk_source_clock = clk_index;
110115

111116
/* enable MCLK divider */
112117
mdivc |= MN_MDIVCTRL_M_DIV_ENABLE;
@@ -125,9 +130,11 @@ static inline int setup_initial_mclk_source(uint32_t mclk_rate)
125130
*/
126131
static inline int check_current_mclk_source(uint32_t mclk_rate)
127132
{
128-
if (ssp_freq[mn.mclk_source_clock].freq % mclk_rate != 0) {
133+
struct mn *mn = mn_get();
134+
135+
if (ssp_freq[mn->mclk_source_clock].freq % mclk_rate != 0) {
129136
trace_mn_error("error: MCLK %d, no valid configuration for already selected source = %d",
130-
mclk_rate, mn.mclk_source_clock);
137+
mclk_rate, mn->mclk_source_clock);
131138
return -EINVAL;
132139
}
133140
return 0;
@@ -167,6 +174,7 @@ static inline int set_mclk_divider(uint16_t mclk_id, uint32_t mdivr_val)
167174

168175
int mn_set_mclk(uint16_t mclk_id, uint32_t mclk_rate)
169176
{
177+
struct mn *mn = mn_get();
170178
int ret = 0;
171179

172180
if (mclk_id >= DAI_NUM_SSP_MCLK) {
@@ -175,9 +183,9 @@ int mn_set_mclk(uint16_t mclk_id, uint32_t mclk_rate)
175183
return -EINVAL;
176184
}
177185

178-
spin_lock(&mn.lock);
186+
spin_lock(&mn->lock);
179187

180-
mn.mclk_sources_used[mclk_id] = false;
188+
mn->mclk_sources_used[mclk_id] = false;
181189

182190
if (is_mclk_source_in_use())
183191
ret = check_current_mclk_source(mclk_rate);
@@ -187,22 +195,25 @@ int mn_set_mclk(uint16_t mclk_id, uint32_t mclk_rate)
187195
if (ret < 0)
188196
goto out;
189197

190-
mn.mclk_sources_used[mclk_id] = true;
198+
mn->mclk_sources_used[mclk_id] = true;
191199

192200
ret = set_mclk_divider(mclk_id,
193-
ssp_freq[mn.mclk_source_clock].freq / mclk_rate);
201+
ssp_freq[mn->mclk_source_clock].freq /
202+
mclk_rate);
194203

195204
out:
196-
spin_unlock(&mn.lock);
205+
spin_unlock(&mn->lock);
197206

198207
return ret;
199208
}
200209

201210
void mn_release_mclk(uint32_t mclk_id)
202211
{
203-
spin_lock(&mn.lock);
204-
mn.mclk_sources_used[mclk_id] = false;
205-
spin_unlock(&mn.lock);
212+
struct mn *mn = mn_get();
213+
214+
spin_lock(&mn->lock);
215+
mn->mclk_sources_used[mclk_id] = false;
216+
spin_unlock(&mn->lock);
206217
}
207218

208219
/**
@@ -299,10 +310,11 @@ static int find_bclk_source(uint32_t bclk,
299310
*/
300311
static inline bool is_bclk_source_in_use(enum bclk_source clk_src)
301312
{
313+
struct mn *mn = mn_get();
302314
int i;
303315

304-
for (i = 0; i < ARRAY_SIZE(mn.bclk_sources); i++)
305-
if (mn.bclk_sources[i] == clk_src)
316+
for (i = 0; i < ARRAY_SIZE(mn->bclk_sources); i++)
317+
if (mn->bclk_sources[i] == clk_src)
306318
return true;
307319
return false;
308320
}
@@ -320,14 +332,15 @@ static inline bool is_bclk_source_in_use(enum bclk_source clk_src)
320332
static inline int setup_initial_bclk_mn_source(uint32_t bclk, uint32_t *scr_div,
321333
uint32_t *m, uint32_t *n)
322334
{
335+
struct mn *mn = mn_get();
323336
int clk_index = find_bclk_source(bclk, scr_div, m, n);
324337

325338
if (clk_index < 0) {
326339
trace_mn_error("error: BCLK %d, no valid source", bclk);
327340
return -EINVAL;
328341
}
329342

330-
mn.bclk_source_mn_clock = clk_index;
343+
mn->bclk_source_mn_clock = clk_index;
331344

332345
mn_reg_write(MN_MDIVCTRL, (mn_reg_read(MN_MDIVCTRL) |
333346
MNDSS(ssp_freq_sources[clk_index])));
@@ -346,13 +359,15 @@ static inline int setup_initial_bclk_mn_source(uint32_t bclk, uint32_t *scr_div,
346359
static inline int setup_current_bclk_mn_source(uint32_t bclk, uint32_t *scr_div,
347360
uint32_t *m, uint32_t *n)
348361
{
362+
struct mn *mn = mn_get();
363+
349364
/* source for M/N is already set, no need to do it */
350-
if (find_mn(ssp_freq[mn.bclk_source_mn_clock].freq, bclk, scr_div, m,
365+
if (find_mn(ssp_freq[mn->bclk_source_mn_clock].freq, bclk, scr_div, m,
351366
n))
352367
return 0;
353368

354369
trace_mn_error("error: BCLK %d, no valid configuration for already selected source = %d",
355-
bclk, mn.bclk_source_mn_clock);
370+
bclk, mn->bclk_source_mn_clock);
356371
return -EINVAL;
357372
}
358373

@@ -376,6 +391,7 @@ static inline bool check_bclk_xtal_source(uint32_t bclk, bool mn_in_use,
376391
static inline bool check_bclk_xtal_source(uint32_t bclk, bool mn_in_use,
377392
uint32_t *scr_div)
378393
{
394+
struct mn *mn = mn_get();
379395
int i;
380396

381397
for (i = 0; i <= MAX_SSP_FREQ_INDEX; i++) {
@@ -393,7 +409,7 @@ static inline bool check_bclk_xtal_source(uint32_t bclk, bool mn_in_use,
393409
/* if M/N is already set up for desired clock,
394410
* we can quit and let M/N logic handle it
395411
*/
396-
if (!mn_in_use || mn.bclk_source_mn_clock == i)
412+
if (!mn_in_use || mn->bclk_source_mn_clock == i)
397413
return false;
398414
}
399415

@@ -404,19 +420,20 @@ static inline bool check_bclk_xtal_source(uint32_t bclk, bool mn_in_use,
404420
int mn_set_bclk(uint32_t dai_index, uint32_t bclk_rate,
405421
uint32_t *out_scr_div, bool *out_need_ecs)
406422
{
423+
struct mn *mn = mn_get();
407424
uint32_t m = 1;
408425
uint32_t n = 1;
409426
int ret = 0;
410427
bool mn_in_use;
411428

412-
spin_lock(&mn.lock);
429+
spin_lock(&mn->lock);
413430

414-
mn.bclk_sources[dai_index] = MN_BCLK_SOURCE_NONE;
431+
mn->bclk_sources[dai_index] = MN_BCLK_SOURCE_NONE;
415432

416433
mn_in_use = is_bclk_source_in_use(MN_BCLK_SOURCE_MN);
417434

418435
if (check_bclk_xtal_source(bclk_rate, mn_in_use, out_scr_div)) {
419-
mn.bclk_sources[dai_index] = MN_BCLK_SOURCE_XTAL;
436+
mn->bclk_sources[dai_index] = MN_BCLK_SOURCE_XTAL;
420437
*out_need_ecs = false;
421438
goto out;
422439
}
@@ -431,29 +448,33 @@ int mn_set_bclk(uint32_t dai_index, uint32_t bclk_rate,
431448
out_scr_div, &m, &n);
432449

433450
if (ret >= 0) {
434-
mn.bclk_sources[dai_index] = MN_BCLK_SOURCE_MN;
451+
mn->bclk_sources[dai_index] = MN_BCLK_SOURCE_MN;
435452

436453
mn_reg_write(MN_MDIV_M_VAL(dai_index), m);
437454
mn_reg_write(MN_MDIV_N_VAL(dai_index), n);
438455
}
439456

440457
out:
441-
spin_unlock(&mn.lock);
458+
spin_unlock(&mn->lock);
442459

443460
return ret;
444461
}
445462

446463
void mn_release_bclk(uint32_t dai_index)
447464
{
448-
spin_lock(&mn.lock);
449-
mn.bclk_sources[dai_index] = MN_BCLK_SOURCE_NONE;
450-
spin_unlock(&mn.lock);
465+
struct mn *mn = mn_get();
466+
467+
spin_lock(&mn->lock);
468+
mn->bclk_sources[dai_index] = MN_BCLK_SOURCE_NONE;
469+
spin_unlock(&mn->lock);
451470
}
452471

453472
void mn_reset_bclk_divider(uint32_t dai_index)
454473
{
455-
spin_lock(&mn.lock);
474+
struct mn *mn = mn_get();
475+
476+
spin_lock(&mn->lock);
456477
mn_reg_write(MN_MDIV_M_VAL(dai_index), 1);
457478
mn_reg_write(MN_MDIV_N_VAL(dai_index), 1);
458-
spin_unlock(&mn.lock);
479+
spin_unlock(&mn->lock);
459480
}

src/include/sof/drivers/mn.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#ifndef __SOF_DRIVERS_MN_H__
99
#define __SOF_DRIVERS_MN_H__
1010

11+
#include <sof/sof.h>
1112
#include <stdbool.h>
1213
#include <stdint.h>
1314

@@ -29,7 +30,7 @@
2930
/**
3031
* \brief Initializes MN driver.
3132
*/
32-
void mn_init(void);
33+
void mn_init(struct sof *sof);
3334

3435
/**
3536
* \brief Finds and sets valid combination of MCLK source and divider to
@@ -77,4 +78,13 @@ void mn_release_bclk(uint32_t dai_index);
7778
*/
7879
void mn_reset_bclk_divider(uint32_t dai_index);
7980

81+
/**
82+
* \brief Retrieves M/N dividers structure.
83+
* \return Pointer to M/N dividers structure.
84+
*/
85+
static inline struct mn *mn_get(void)
86+
{
87+
return sof_get()->mn;
88+
}
89+
8090
#endif /* __SOF_DRIVERS_MN_H__ */

src/include/sof/sof.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct dma_trace_data;
2121
struct ipc;
2222
struct ll_schedule_domain;
2323
struct mm;
24+
struct mn;
2425
struct notify_data;
2526
struct pm_runtime_data;
2627
struct sa;
@@ -87,6 +88,9 @@ struct sof {
8788
/* list of registered component drivers */
8889
struct comp_driver_list *comp_drivers;
8990

91+
/* M/N dividers */
92+
struct mn *mn;
93+
9094
__aligned(PLATFORM_DCACHE_ALIGN) int alignment[0];
9195
} __aligned(PLATFORM_DCACHE_ALIGN);
9296

src/platform/intel/cavs/lib/dai.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ int dai_init(struct sof *sof)
155155
#endif
156156

157157
#if CONFIG_CAVS_MN
158-
mn_init();
158+
mn_init(sof);
159159
#endif
160160

161161
dai = cache_to_uncache((struct dai *)hda);

0 commit comments

Comments
 (0)