Skip to content

Commit d341ca8

Browse files
jbrun3tstorulf
authored andcommitted
mmc: meson-gx: rework tuning function
Rework tuning function of the rx phase. Now that the phase can be more precisely set using CCF, test more phase setting and find the largest working window. Then the tuning selected is the one at the center of the window. This rework allows to use new modes, such as UHS SDR50 Reviewed-by: Kevin Hilman <[email protected]> Signed-off-by: Jerome Brunet <[email protected]> Signed-off-by: Ulf Hansson <[email protected]>
1 parent bac135d commit d341ca8

File tree

1 file changed

+111
-50
lines changed

1 file changed

+111
-50
lines changed

drivers/mmc/host/meson-gx-mmc.c

Lines changed: 111 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
#define CLK_TX_DELAY_MASK GENMASK(19, 16)
5050
#define CLK_RX_DELAY_MASK GENMASK(23, 20)
5151
#define CLK_DELAY_STEP_PS 200
52+
#define CLK_PHASE_STEP 30
53+
#define CLK_PHASE_POINT_NUM (360 / CLK_PHASE_STEP)
5254
#define CLK_ALWAYS_ON BIT(24)
5355

5456
#define SD_EMMC_DELAY 0x4
@@ -119,12 +121,6 @@
119121

120122
#define MUX_CLK_NUM_PARENTS 2
121123

122-
struct meson_tuning_params {
123-
unsigned int core_phase;
124-
unsigned int tx_phase;
125-
unsigned int rx_phase;
126-
};
127-
128124
struct sd_emmc_desc {
129125
u32 cmd_cfg;
130126
u32 cmd_arg;
@@ -155,7 +151,6 @@ struct meson_host {
155151
struct sd_emmc_desc *descs;
156152
dma_addr_t descs_dma_addr;
157153

158-
struct meson_tuning_params tp;
159154
bool vqmmc_enabled;
160155
};
161156

@@ -458,13 +453,6 @@ static int meson_mmc_clk_set(struct meson_host *host, struct mmc_ios *ios)
458453
return 0;
459454
}
460455

461-
static void meson_mmc_set_phase_params(struct meson_host *host)
462-
{
463-
clk_set_phase(host->mmc_clk, host->tp.core_phase);
464-
clk_set_phase(host->tx_clk, host->tp.tx_phase);
465-
clk_set_phase(host->rx_clk, host->tp.rx_phase);
466-
}
467-
468456
/*
469457
* The SD/eMMC IP block has an internal mux and divider used for
470458
* generating the MMC clock. Use the clock framework to create and
@@ -617,18 +605,122 @@ static int meson_mmc_clk_init(struct meson_host *host)
617605
if (WARN_ON(PTR_ERR_OR_ZERO(host->rx_clk)))
618606
return PTR_ERR(host->rx_clk);
619607

620-
/* Set the initial phase parameters */
621-
meson_mmc_set_phase_params(host);
622-
623608
/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
624609
host->mmc->f_min = clk_round_rate(host->mmc_clk, 400000);
625610
ret = clk_set_rate(host->mmc_clk, host->mmc->f_min);
626611
if (ret)
627612
return ret;
628613

614+
/*
615+
* Set phases : These values are mostly the datasheet recommended ones
616+
* except for the Tx phase. Datasheet recommends 180 but some cards
617+
* fail at initialisation with it. 270 works just fine, it fixes these
618+
* initialisation issues and enable eMMC DDR52 mode.
619+
*/
620+
clk_set_phase(host->mmc_clk, 180);
621+
clk_set_phase(host->tx_clk, 270);
622+
clk_set_phase(host->rx_clk, 0);
623+
629624
return clk_prepare_enable(host->mmc_clk);
630625
}
631626

627+
static void meson_mmc_shift_map(unsigned long *map, unsigned long shift)
628+
{
629+
DECLARE_BITMAP(left, CLK_PHASE_POINT_NUM);
630+
DECLARE_BITMAP(right, CLK_PHASE_POINT_NUM);
631+
632+
/*
633+
* shift the bitmap right and reintroduce the dropped bits on the left
634+
* of the bitmap
635+
*/
636+
bitmap_shift_right(right, map, shift, CLK_PHASE_POINT_NUM);
637+
bitmap_shift_left(left, map, CLK_PHASE_POINT_NUM - shift,
638+
CLK_PHASE_POINT_NUM);
639+
bitmap_or(map, left, right, CLK_PHASE_POINT_NUM);
640+
}
641+
642+
static void meson_mmc_find_next_region(unsigned long *map,
643+
unsigned long *start,
644+
unsigned long *stop)
645+
{
646+
*start = find_next_bit(map, CLK_PHASE_POINT_NUM, *start);
647+
*stop = find_next_zero_bit(map, CLK_PHASE_POINT_NUM, *start);
648+
}
649+
650+
static int meson_mmc_find_tuning_point(unsigned long *test)
651+
{
652+
unsigned long shift, stop, offset = 0, start = 0, size = 0;
653+
654+
/* Get the all good/all bad situation out the way */
655+
if (bitmap_full(test, CLK_PHASE_POINT_NUM))
656+
return 0; /* All points are good so point 0 will do */
657+
else if (bitmap_empty(test, CLK_PHASE_POINT_NUM))
658+
return -EIO; /* No successful tuning point */
659+
660+
/*
661+
* Now we know there is a least one region find. Make sure it does
662+
* not wrap by the shifting the bitmap if necessary
663+
*/
664+
shift = find_first_zero_bit(test, CLK_PHASE_POINT_NUM);
665+
if (shift != 0)
666+
meson_mmc_shift_map(test, shift);
667+
668+
while (start < CLK_PHASE_POINT_NUM) {
669+
meson_mmc_find_next_region(test, &start, &stop);
670+
671+
if ((stop - start) > size) {
672+
offset = start;
673+
size = stop - start;
674+
}
675+
676+
start = stop;
677+
}
678+
679+
/* Get the center point of the region */
680+
offset += (size / 2);
681+
682+
/* Shift the result back */
683+
offset = (offset + shift) % CLK_PHASE_POINT_NUM;
684+
685+
return offset;
686+
}
687+
688+
static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode,
689+
struct clk *clk)
690+
{
691+
int point, ret;
692+
DECLARE_BITMAP(test, CLK_PHASE_POINT_NUM);
693+
694+
dev_dbg(mmc_dev(mmc), "%s phase/delay tunning...\n",
695+
__clk_get_name(clk));
696+
bitmap_zero(test, CLK_PHASE_POINT_NUM);
697+
698+
/* Explore tuning points */
699+
for (point = 0; point < CLK_PHASE_POINT_NUM; point++) {
700+
clk_set_phase(clk, point * CLK_PHASE_STEP);
701+
ret = mmc_send_tuning(mmc, opcode, NULL);
702+
if (!ret)
703+
set_bit(point, test);
704+
}
705+
706+
/* Find the optimal tuning point and apply it */
707+
point = meson_mmc_find_tuning_point(test);
708+
if (point < 0)
709+
return point; /* tuning failed */
710+
711+
clk_set_phase(clk, point * CLK_PHASE_STEP);
712+
dev_dbg(mmc_dev(mmc), "success with phase: %d\n",
713+
clk_get_phase(clk));
714+
return 0;
715+
}
716+
717+
static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
718+
{
719+
struct meson_host *host = mmc_priv(mmc);
720+
721+
return meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk);
722+
}
723+
632724
static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
633725
{
634726
struct meson_host *host = mmc_priv(mmc);
@@ -667,6 +759,8 @@ static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
667759
host->vqmmc_enabled = true;
668760
}
669761

762+
/* Reset rx phase */
763+
clk_set_phase(host->rx_clk, 0);
670764
break;
671765
}
672766

@@ -989,29 +1083,6 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
9891083
return IRQ_HANDLED;
9901084
}
9911085

992-
static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
993-
{
994-
struct meson_host *host = mmc_priv(mmc);
995-
struct meson_tuning_params tp_old = host->tp;
996-
int ret = -EINVAL, i, cmd_error;
997-
998-
dev_info(mmc_dev(mmc), "(re)tuning...\n");
999-
1000-
for (i = 0; i < 360; i += 90) {
1001-
host->tp.rx_phase = i;
1002-
/* exclude the active parameter set if retuning */
1003-
if (!memcmp(&tp_old, &host->tp, sizeof(tp_old)) &&
1004-
mmc->doing_retune)
1005-
continue;
1006-
meson_mmc_set_phase_params(host);
1007-
ret = mmc_send_tuning(mmc, opcode, &cmd_error);
1008-
if (!ret)
1009-
break;
1010-
}
1011-
1012-
return ret;
1013-
}
1014-
10151086
/*
10161087
* NOTE: we only need this until the GPIO/pinctrl driver can handle
10171088
* interrupts. For now, the MMC core will use this for polling.
@@ -1156,16 +1227,6 @@ static int meson_mmc_probe(struct platform_device *pdev)
11561227
if (ret)
11571228
goto free_host;
11581229

1159-
/*
1160-
* Set phases : These values are mostly the datasheet recommended ones
1161-
* except for the Tx phase. Datasheet recommends 180 but some cards
1162-
* fail at initialisation with it. 270 works just fine, it fixes these
1163-
* initialisation issues and enable eMMC DDR52 mode.
1164-
*/
1165-
host->tp.core_phase = 180;
1166-
host->tp.tx_phase = 270;
1167-
host->tp.rx_phase = 0;
1168-
11691230
ret = meson_mmc_clk_init(host);
11701231
if (ret)
11711232
goto err_core_clk;

0 commit comments

Comments
 (0)