Skip to content

Commit 5a8b478

Browse files
TE-N-ShengjiuWangbroonie
authored andcommitted
ASoC: fsl_xcvr: Use regmap for PHY and PLL registers
Define regmap for PHY and PLL registers, the PHY and PLL registers are accessed by AI interface in controller. So that driver can use regcache to recover registers after suspend and resume. Signed-off-by: Shengjiu Wang <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 40384c8 commit 5a8b478

File tree

2 files changed

+191
-46
lines changed

2 files changed

+191
-46
lines changed

sound/soc/fsl/fsl_xcvr.c

Lines changed: 178 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ struct fsl_xcvr {
3737
const struct fsl_xcvr_soc_data *soc_data;
3838
struct platform_device *pdev;
3939
struct regmap *regmap;
40+
struct regmap *regmap_phy;
41+
struct regmap *regmap_pll;
4042
struct clk *ipg_clk;
4143
struct clk *pll_ipg_clk;
4244
struct clk *phy_clk;
@@ -257,7 +259,7 @@ static int fsl_xcvr_ai_write(struct fsl_xcvr *xcvr, u8 reg, u32 data, bool phy)
257259
idx = BIT(phy ? 26 : 24);
258260
tidx = BIT(phy ? 27 : 25);
259261

260-
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_CLR, 0xFF);
262+
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_CLR, 0xFF | FSL_XCVR_PHY_AI_CTRL_AI_RWB);
261263
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET, reg);
262264
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_WDATA, data);
263265
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_TOG, idx);
@@ -271,6 +273,59 @@ static int fsl_xcvr_ai_write(struct fsl_xcvr *xcvr, u8 reg, u32 data, bool phy)
271273
return ret;
272274
}
273275

276+
static int fsl_xcvr_ai_read(struct fsl_xcvr *xcvr, u8 reg, u32 *data, bool phy)
277+
{
278+
struct device *dev = &xcvr->pdev->dev;
279+
u32 val, idx, tidx;
280+
int ret;
281+
282+
idx = BIT(phy ? 26 : 24);
283+
tidx = BIT(phy ? 27 : 25);
284+
285+
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_CLR, 0xFF | FSL_XCVR_PHY_AI_CTRL_AI_RWB);
286+
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET, reg | FSL_XCVR_PHY_AI_CTRL_AI_RWB);
287+
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_TOG, idx);
288+
289+
ret = regmap_read_poll_timeout(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL, val,
290+
(val & idx) == ((val & tidx) >> 1),
291+
10, 10000);
292+
if (ret)
293+
dev_err(dev, "AI timeout: failed to read %s reg 0x%02x\n",
294+
phy ? "PHY" : "PLL", reg);
295+
296+
regmap_read(xcvr->regmap, FSL_XCVR_PHY_AI_RDATA, data);
297+
298+
return ret;
299+
}
300+
301+
static int fsl_xcvr_phy_reg_read(void *context, unsigned int reg, unsigned int *val)
302+
{
303+
struct fsl_xcvr *xcvr = context;
304+
305+
return fsl_xcvr_ai_read(xcvr, reg, val, 1);
306+
}
307+
308+
static int fsl_xcvr_phy_reg_write(void *context, unsigned int reg, unsigned int val)
309+
{
310+
struct fsl_xcvr *xcvr = context;
311+
312+
return fsl_xcvr_ai_write(xcvr, reg, val, 1);
313+
}
314+
315+
static int fsl_xcvr_pll_reg_read(void *context, unsigned int reg, unsigned int *val)
316+
{
317+
struct fsl_xcvr *xcvr = context;
318+
319+
return fsl_xcvr_ai_read(xcvr, reg, val, 0);
320+
}
321+
322+
static int fsl_xcvr_pll_reg_write(void *context, unsigned int reg, unsigned int val)
323+
{
324+
struct fsl_xcvr *xcvr = context;
325+
326+
return fsl_xcvr_ai_write(xcvr, reg, val, 0);
327+
}
328+
274329
static int fsl_xcvr_en_phy_pll(struct fsl_xcvr *xcvr, u32 freq, bool tx)
275330
{
276331
struct device *dev = &xcvr->pdev->dev;
@@ -303,55 +358,55 @@ static int fsl_xcvr_en_phy_pll(struct fsl_xcvr *xcvr, u32 freq, bool tx)
303358
switch (xcvr->soc_data->pll_ver) {
304359
case PLL_MX8MP:
305360
/* PLL: BANDGAP_SET: EN_VBG (enable bandgap) */
306-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_BANDGAP_SET,
307-
FSL_XCVR_PLL_BANDGAP_EN_VBG, 0);
361+
regmap_set_bits(xcvr->regmap_pll, FSL_XCVR_PLL_BANDGAP,
362+
FSL_XCVR_PLL_BANDGAP_EN_VBG);
308363

309364
/* PLL: CTRL0: DIV_INTEGER */
310-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0, fsl_xcvr_pll_cfg[i].mfi, 0);
365+
regmap_write(xcvr->regmap_pll, FSL_XCVR_PLL_CTRL0, fsl_xcvr_pll_cfg[i].mfi);
311366
/* PLL: NUMERATOR: MFN */
312-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_NUM, fsl_xcvr_pll_cfg[i].mfn, 0);
367+
regmap_write(xcvr->regmap_pll, FSL_XCVR_PLL_NUM, fsl_xcvr_pll_cfg[i].mfn);
313368
/* PLL: DENOMINATOR: MFD */
314-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_DEN, fsl_xcvr_pll_cfg[i].mfd, 0);
369+
regmap_write(xcvr->regmap_pll, FSL_XCVR_PLL_DEN, fsl_xcvr_pll_cfg[i].mfd);
315370
/* PLL: CTRL0_SET: HOLD_RING_OFF, POWER_UP */
316-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_SET,
317-
FSL_XCVR_PLL_CTRL0_HROFF | FSL_XCVR_PLL_CTRL0_PWP, 0);
371+
regmap_set_bits(xcvr->regmap_pll, FSL_XCVR_PLL_CTRL0,
372+
FSL_XCVR_PLL_CTRL0_HROFF | FSL_XCVR_PLL_CTRL0_PWP);
318373
udelay(25);
319374
/* PLL: CTRL0: Clear Hold Ring Off */
320-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_CLR,
321-
FSL_XCVR_PLL_CTRL0_HROFF, 0);
375+
regmap_clear_bits(xcvr->regmap_pll, FSL_XCVR_PLL_CTRL0,
376+
FSL_XCVR_PLL_CTRL0_HROFF);
322377
udelay(100);
323378
if (tx) { /* TX is enabled for SPDIF only */
324379
/* PLL: POSTDIV: PDIV0 */
325-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_PDIV,
326-
FSL_XCVR_PLL_PDIVx(log2, 0), 0);
380+
regmap_write(xcvr->regmap_pll, FSL_XCVR_PLL_PDIV,
381+
FSL_XCVR_PLL_PDIVx(log2, 0));
327382
/* PLL: CTRL_SET: CLKMUX0_EN */
328-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_SET,
329-
FSL_XCVR_PLL_CTRL0_CM0_EN, 0);
383+
regmap_set_bits(xcvr->regmap_pll, FSL_XCVR_PLL_CTRL0,
384+
FSL_XCVR_PLL_CTRL0_CM0_EN);
330385
} else if (xcvr->mode == FSL_XCVR_MODE_EARC) { /* eARC RX */
331386
/* PLL: POSTDIV: PDIV1 */
332-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_PDIV,
333-
FSL_XCVR_PLL_PDIVx(log2, 1), 0);
387+
regmap_write(xcvr->regmap_pll, FSL_XCVR_PLL_PDIV,
388+
FSL_XCVR_PLL_PDIVx(log2, 1));
334389
/* PLL: CTRL_SET: CLKMUX1_EN */
335-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_SET,
336-
FSL_XCVR_PLL_CTRL0_CM1_EN, 0);
390+
regmap_set_bits(xcvr->regmap_pll, FSL_XCVR_PLL_CTRL0,
391+
FSL_XCVR_PLL_CTRL0_CM1_EN);
337392
} else { /* SPDIF / ARC RX */
338393
/* PLL: POSTDIV: PDIV2 */
339-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_PDIV,
340-
FSL_XCVR_PLL_PDIVx(log2, 2), 0);
394+
regmap_write(xcvr->regmap_pll, FSL_XCVR_PLL_PDIV,
395+
FSL_XCVR_PLL_PDIVx(log2, 2));
341396
/* PLL: CTRL_SET: CLKMUX2_EN */
342-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_SET,
343-
FSL_XCVR_PLL_CTRL0_CM2_EN, 0);
397+
regmap_set_bits(xcvr->regmap_pll, FSL_XCVR_PLL_CTRL0,
398+
FSL_XCVR_PLL_CTRL0_CM2_EN);
344399
}
345400
break;
346401
case PLL_MX95:
347402
val = fsl_xcvr_pll_cfg[i].mfi << FSL_XCVR_GP_PLL_DIV_MFI_SHIFT | div;
348-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_GP_PLL_DIV, val, 0);
403+
regmap_write(xcvr->regmap_pll, FSL_XCVR_GP_PLL_DIV, val);
349404
val = fsl_xcvr_pll_cfg[i].mfn << FSL_XCVR_GP_PLL_NUMERATOR_MFN_SHIFT;
350-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_GP_PLL_NUMERATOR, val, 0);
351-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_GP_PLL_DENOMINATOR,
352-
fsl_xcvr_pll_cfg[i].mfd, 0);
405+
regmap_write(xcvr->regmap_pll, FSL_XCVR_GP_PLL_NUMERATOR, val);
406+
regmap_write(xcvr->regmap_pll, FSL_XCVR_GP_PLL_DENOMINATOR,
407+
fsl_xcvr_pll_cfg[i].mfd);
353408
val = FSL_XCVR_GP_PLL_CTRL_POWERUP | FSL_XCVR_GP_PLL_CTRL_CLKMUX_EN;
354-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_GP_PLL_CTRL, val, 0);
409+
regmap_write(xcvr->regmap_pll, FSL_XCVR_GP_PLL_CTRL, val);
355410
break;
356411
default:
357412
dev_err(dev, "Error for PLL version %d\n", xcvr->soc_data->pll_ver);
@@ -360,22 +415,22 @@ static int fsl_xcvr_en_phy_pll(struct fsl_xcvr *xcvr, u32 freq, bool tx)
360415

361416
if (xcvr->mode == FSL_XCVR_MODE_EARC) { /* eARC mode */
362417
/* PHY: CTRL_SET: TX_DIFF_OE, PHY_EN */
363-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
364-
FSL_XCVR_PHY_CTRL_TSDIFF_OE |
365-
FSL_XCVR_PHY_CTRL_PHY_EN, 1);
418+
regmap_set_bits(xcvr->regmap_phy, FSL_XCVR_PHY_CTRL,
419+
FSL_XCVR_PHY_CTRL_TSDIFF_OE |
420+
FSL_XCVR_PHY_CTRL_PHY_EN);
366421
/* PHY: CTRL2_SET: EARC_TX_MODE */
367-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL2_SET,
368-
FSL_XCVR_PHY_CTRL2_EARC_TXMS, 1);
422+
regmap_set_bits(xcvr->regmap_phy, FSL_XCVR_PHY_CTRL2,
423+
FSL_XCVR_PHY_CTRL2_EARC_TXMS);
369424
} else if (!tx) { /* SPDIF / ARC RX mode */
370425
if (xcvr->mode == FSL_XCVR_MODE_SPDIF)
371426
/* PHY: CTRL_SET: SPDIF_EN */
372-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
373-
FSL_XCVR_PHY_CTRL_SPDIF_EN, 1);
427+
regmap_set_bits(xcvr->regmap_phy, FSL_XCVR_PHY_CTRL,
428+
FSL_XCVR_PHY_CTRL_SPDIF_EN);
374429
else /* PHY: CTRL_SET: ARC RX setup */
375-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
376-
FSL_XCVR_PHY_CTRL_PHY_EN |
377-
FSL_XCVR_PHY_CTRL_RX_CM_EN |
378-
fsl_xcvr_phy_arc_cfg[xcvr->arc_mode], 1);
430+
regmap_set_bits(xcvr->regmap_phy, FSL_XCVR_PHY_CTRL,
431+
FSL_XCVR_PHY_CTRL_PHY_EN |
432+
FSL_XCVR_PHY_CTRL_RX_CM_EN |
433+
fsl_xcvr_phy_arc_cfg[xcvr->arc_mode]);
379434
}
380435

381436
dev_dbg(dev, "PLL Fexp: %u, Fout: %u, mfi: %u, mfn: %u, mfd: %d, div: %u, pdiv0: %u\n",
@@ -416,17 +471,17 @@ static int fsl_xcvr_en_aud_pll(struct fsl_xcvr *xcvr, u32 freq)
416471

417472
if (xcvr->mode == FSL_XCVR_MODE_EARC) { /* eARC mode */
418473
/* PHY: CTRL_SET: TX_DIFF_OE, PHY_EN */
419-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
420-
FSL_XCVR_PHY_CTRL_TSDIFF_OE |
421-
FSL_XCVR_PHY_CTRL_PHY_EN, 1);
474+
regmap_set_bits(xcvr->regmap_phy, FSL_XCVR_PHY_CTRL,
475+
FSL_XCVR_PHY_CTRL_TSDIFF_OE |
476+
FSL_XCVR_PHY_CTRL_PHY_EN);
422477
/* PHY: CTRL2_SET: EARC_TX_MODE */
423-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL2_SET,
424-
FSL_XCVR_PHY_CTRL2_EARC_TXMS, 1);
478+
regmap_set_bits(xcvr->regmap_phy, FSL_XCVR_PHY_CTRL2,
479+
FSL_XCVR_PHY_CTRL2_EARC_TXMS);
425480
} else { /* SPDIF mode */
426481
/* PHY: CTRL_SET: TX_CLK_AUD_SS | SPDIF_EN */
427-
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
428-
FSL_XCVR_PHY_CTRL_TX_CLK_AUD_SS |
429-
FSL_XCVR_PHY_CTRL_SPDIF_EN, 1);
482+
regmap_set_bits(xcvr->regmap_phy, FSL_XCVR_PHY_CTRL,
483+
FSL_XCVR_PHY_CTRL_TX_CLK_AUD_SS |
484+
FSL_XCVR_PHY_CTRL_SPDIF_EN);
430485
}
431486

432487
dev_dbg(dev, "PLL Fexp: %u\n", freq);
@@ -1206,6 +1261,49 @@ static const struct regmap_config fsl_xcvr_regmap_cfg = {
12061261
.cache_type = REGCACHE_FLAT,
12071262
};
12081263

1264+
static const struct reg_default fsl_xcvr_phy_reg_defaults[] = {
1265+
{ FSL_XCVR_PHY_CTRL, 0x58200804 },
1266+
{ FSL_XCVR_PHY_STATUS, 0x00000000 },
1267+
{ FSL_XCVR_PHY_ANALOG_TRIM, 0x00260F13 },
1268+
{ FSL_XCVR_PHY_SLEW_RATE_TRIM, 0x00000411 },
1269+
{ FSL_XCVR_PHY_DATA_TEST_DELAY, 0x00990000 },
1270+
{ FSL_XCVR_PHY_TEST_CTRL, 0x00000000 },
1271+
{ FSL_XCVR_PHY_DIFF_CDR_CTRL, 0x016D0009 },
1272+
{ FSL_XCVR_PHY_CTRL2, 0x80000000 },
1273+
};
1274+
1275+
static const struct regmap_config fsl_xcvr_regmap_phy_cfg = {
1276+
.reg_bits = 8,
1277+
.reg_stride = 4,
1278+
.val_bits = 32,
1279+
.max_register = FSL_XCVR_PHY_CTRL2_TOG,
1280+
.reg_defaults = fsl_xcvr_phy_reg_defaults,
1281+
.num_reg_defaults = ARRAY_SIZE(fsl_xcvr_phy_reg_defaults),
1282+
.cache_type = REGCACHE_FLAT,
1283+
.reg_read = fsl_xcvr_phy_reg_read,
1284+
.reg_write = fsl_xcvr_phy_reg_write,
1285+
};
1286+
1287+
static const struct regmap_config fsl_xcvr_regmap_pllv0_cfg = {
1288+
.reg_bits = 8,
1289+
.reg_stride = 4,
1290+
.val_bits = 32,
1291+
.max_register = FSL_XCVR_PLL_STAT0_TOG,
1292+
.cache_type = REGCACHE_FLAT,
1293+
.reg_read = fsl_xcvr_pll_reg_read,
1294+
.reg_write = fsl_xcvr_pll_reg_write,
1295+
};
1296+
1297+
static const struct regmap_config fsl_xcvr_regmap_pllv1_cfg = {
1298+
.reg_bits = 8,
1299+
.reg_stride = 4,
1300+
.val_bits = 32,
1301+
.max_register = FSL_XCVR_GP_PLL_STATUS_TOG,
1302+
.cache_type = REGCACHE_FLAT,
1303+
.reg_read = fsl_xcvr_pll_reg_read,
1304+
.reg_write = fsl_xcvr_pll_reg_write,
1305+
};
1306+
12091307
static void reset_rx_work(struct work_struct *work)
12101308
{
12111309
struct fsl_xcvr *xcvr = container_of(work, struct fsl_xcvr, work_rst);
@@ -1421,6 +1519,40 @@ static int fsl_xcvr_probe(struct platform_device *pdev)
14211519
return PTR_ERR(xcvr->regmap);
14221520
}
14231521

1522+
if (xcvr->soc_data->use_phy) {
1523+
xcvr->regmap_phy = devm_regmap_init(dev, NULL, xcvr,
1524+
&fsl_xcvr_regmap_phy_cfg);
1525+
if (IS_ERR(xcvr->regmap_phy)) {
1526+
dev_err(dev, "failed to init XCVR PHY regmap: %ld\n",
1527+
PTR_ERR(xcvr->regmap_phy));
1528+
return PTR_ERR(xcvr->regmap_phy);
1529+
}
1530+
1531+
switch (xcvr->soc_data->pll_ver) {
1532+
case PLL_MX8MP:
1533+
xcvr->regmap_pll = devm_regmap_init(dev, NULL, xcvr,
1534+
&fsl_xcvr_regmap_pllv0_cfg);
1535+
if (IS_ERR(xcvr->regmap_pll)) {
1536+
dev_err(dev, "failed to init XCVR PLL regmap: %ld\n",
1537+
PTR_ERR(xcvr->regmap_pll));
1538+
return PTR_ERR(xcvr->regmap_pll);
1539+
}
1540+
break;
1541+
case PLL_MX95:
1542+
xcvr->regmap_pll = devm_regmap_init(dev, NULL, xcvr,
1543+
&fsl_xcvr_regmap_pllv1_cfg);
1544+
if (IS_ERR(xcvr->regmap_pll)) {
1545+
dev_err(dev, "failed to init XCVR PLL regmap: %ld\n",
1546+
PTR_ERR(xcvr->regmap_pll));
1547+
return PTR_ERR(xcvr->regmap_pll);
1548+
}
1549+
break;
1550+
default:
1551+
dev_err(dev, "Error for PLL version %d\n", xcvr->soc_data->pll_ver);
1552+
return -EINVAL;
1553+
}
1554+
}
1555+
14241556
xcvr->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
14251557
if (IS_ERR(xcvr->reset)) {
14261558
dev_err(dev, "failed to get XCVR reset control\n");

sound/soc/fsl/fsl_xcvr.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,20 +234,33 @@
234234
#define FSL_XCVR_TX_DPTH_CTRL_TM_NO_PRE_BME GENMASK(31, 30)
235235

236236
#define FSL_XCVR_PHY_AI_CTRL_AI_RESETN BIT(15)
237+
#define FSL_XCVR_PHY_AI_CTRL_AI_RWB BIT(31)
237238

238239
#define FSL_XCVR_PLL_CTRL0 0x00
239240
#define FSL_XCVR_PLL_CTRL0_SET 0x04
240241
#define FSL_XCVR_PLL_CTRL0_CLR 0x08
241242
#define FSL_XCVR_PLL_NUM 0x20
242243
#define FSL_XCVR_PLL_DEN 0x30
243244
#define FSL_XCVR_PLL_PDIV 0x40
245+
#define FSL_XCVR_PLL_BANDGAP 0x50
244246
#define FSL_XCVR_PLL_BANDGAP_SET 0x54
247+
#define FSL_XCVR_PLL_STAT0 0x60
248+
#define FSL_XCVR_PLL_STAT0_TOG 0x6c
249+
245250
#define FSL_XCVR_PHY_CTRL 0x00
246251
#define FSL_XCVR_PHY_CTRL_SET 0x04
247252
#define FSL_XCVR_PHY_CTRL_CLR 0x08
253+
#define FSL_XCVR_PHY_CTRL_TOG 0x0c
254+
#define FSL_XCVR_PHY_STATUS 0x10
255+
#define FSL_XCVR_PHY_ANALOG_TRIM 0x20
256+
#define FSL_XCVR_PHY_SLEW_RATE_TRIM 0x30
257+
#define FSL_XCVR_PHY_DATA_TEST_DELAY 0x40
258+
#define FSL_XCVR_PHY_TEST_CTRL 0x50
259+
#define FSL_XCVR_PHY_DIFF_CDR_CTRL 0x60
248260
#define FSL_XCVR_PHY_CTRL2 0x70
249261
#define FSL_XCVR_PHY_CTRL2_SET 0x74
250262
#define FSL_XCVR_PHY_CTRL2_CLR 0x78
263+
#define FSL_XCVR_PHY_CTRL2_TOG 0x7c
251264

252265
#define FSL_XCVR_PLL_BANDGAP_EN_VBG BIT(0)
253266
#define FSL_XCVR_PLL_CTRL0_HROFF BIT(13)

0 commit comments

Comments
 (0)