Skip to content

Commit

Permalink
memory: ti-aemif: Store timings parameter in number of cycles - 1
Browse files Browse the repository at this point in the history
The CS configuration register expects timings to be expressed in
'number of cycles - 1' but they are stored in ns in the struct
aemif_cs_data. So at init, the timings currently set are converted to ns
by aemif_get_hw_params(), updated with values from the device-tree
properties, and then converted back to 'number of cycles - 1' before
being applied.

Store the timings directly in 'number of cycles - 1' instead of
nanoseconds.
Perform the conversion from nanosecond during the device-tree parsing.
Remove aemif_cycles_to_nsec() as it isn't used anymore.

Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20241204094319.1050826-2-bastien.curutchet@bootlin.com
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
  • Loading branch information
Bastien Curutchet authored and Krzysztof Kozlowski committed Dec 9, 2024
1 parent 40384c8 commit 1ec0fa9
Showing 1 changed file with 79 additions and 56 deletions.
135 changes: 79 additions & 56 deletions drivers/memory/ti-aemif.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,26 @@
/**
* struct aemif_cs_data: structure to hold cs parameters
* @cs: chip-select number
* @wstrobe: write strobe width, ns
* @rstrobe: read strobe width, ns
* @wsetup: write setup width, ns
* @whold: write hold width, ns
* @rsetup: read setup width, ns
* @rhold: read hold width, ns
* @ta: minimum turn around time, ns
* @wstrobe: write strobe width, number of cycles - 1
* @rstrobe: read strobe width, number of cycles - 1
* @wsetup: write setup width, number of cycles - 1
* @whold: write hold width, number of cycles - 1
* @rsetup: read setup width, number of cycles - 1
* @rhold: read hold width, number of cycles - 1
* @ta: minimum turn around time, number of cycles - 1
* @enable_ss: enable/disable select strobe mode
* @enable_ew: enable/disable extended wait mode
* @asize: width of the asynchronous device's data bus
*/
struct aemif_cs_data {
u8 cs;
u16 wstrobe;
u16 rstrobe;
u8 wsetup;
u8 whold;
u8 rsetup;
u8 rhold;
u8 ta;
u32 wstrobe;
u32 rstrobe;
u32 wsetup;
u32 whold;
u32 rsetup;
u32 rhold;
u32 ta;
u8 enable_ss;
u8 enable_ew;
u8 asize;
Expand Down Expand Up @@ -175,26 +175,18 @@ static int aemif_config_abus(struct platform_device *pdev, int csnum)
struct aemif_device *aemif = platform_get_drvdata(pdev);
struct aemif_cs_data *data = &aemif->cs_data[csnum];
int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
unsigned long clk_rate = aemif->clk_rate;
unsigned offset;
u32 set, val;

offset = A1CR_OFFSET + (data->cs - aemif->cs_offset) * 4;

ta = aemif_calc_rate(pdev, data->ta, clk_rate, TA_MAX);
rhold = aemif_calc_rate(pdev, data->rhold, clk_rate, RHOLD_MAX);
rstrobe = aemif_calc_rate(pdev, data->rstrobe, clk_rate, RSTROBE_MAX);
rsetup = aemif_calc_rate(pdev, data->rsetup, clk_rate, RSETUP_MAX);
whold = aemif_calc_rate(pdev, data->whold, clk_rate, WHOLD_MAX);
wstrobe = aemif_calc_rate(pdev, data->wstrobe, clk_rate, WSTROBE_MAX);
wsetup = aemif_calc_rate(pdev, data->wsetup, clk_rate, WSETUP_MAX);

if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 ||
whold < 0 || wstrobe < 0 || wsetup < 0) {
dev_err(&pdev->dev, "%s: cannot get suitable timings\n",
__func__);
return -EINVAL;
}
ta = data->ta;
rhold = data->rhold;
rstrobe = data->rstrobe;
rsetup = data->rsetup;
whold = data->whold;
wstrobe = data->wstrobe;
wsetup = data->wsetup;

set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) |
WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup);
Expand All @@ -213,11 +205,6 @@ static int aemif_config_abus(struct platform_device *pdev, int csnum)
return 0;
}

static inline int aemif_cycles_to_nsec(int val, unsigned long clk_rate)
{
return ((val + 1) * NSEC_PER_MSEC) / clk_rate;
}

/**
* aemif_get_hw_params - function to read hw register values
* @pdev: platform device to read for
Expand All @@ -231,19 +218,18 @@ static void aemif_get_hw_params(struct platform_device *pdev, int csnum)
{
struct aemif_device *aemif = platform_get_drvdata(pdev);
struct aemif_cs_data *data = &aemif->cs_data[csnum];
unsigned long clk_rate = aemif->clk_rate;
u32 val, offset;

offset = A1CR_OFFSET + (data->cs - aemif->cs_offset) * 4;
val = readl(aemif->base + offset);

data->ta = aemif_cycles_to_nsec(TA_VAL(val), clk_rate);
data->rhold = aemif_cycles_to_nsec(RHOLD_VAL(val), clk_rate);
data->rstrobe = aemif_cycles_to_nsec(RSTROBE_VAL(val), clk_rate);
data->rsetup = aemif_cycles_to_nsec(RSETUP_VAL(val), clk_rate);
data->whold = aemif_cycles_to_nsec(WHOLD_VAL(val), clk_rate);
data->wstrobe = aemif_cycles_to_nsec(WSTROBE_VAL(val), clk_rate);
data->wsetup = aemif_cycles_to_nsec(WSETUP_VAL(val), clk_rate);
data->ta = TA_VAL(val);
data->rhold = RHOLD_VAL(val);
data->rstrobe = RSTROBE_VAL(val);
data->rsetup = RSETUP_VAL(val);
data->whold = WHOLD_VAL(val);
data->wstrobe = WSTROBE_VAL(val);
data->wsetup = WSETUP_VAL(val);
data->enable_ew = EW_VAL(val);
data->enable_ss = SSTROBE_VAL(val);
data->asize = val & ASIZE_MAX;
Expand All @@ -261,7 +247,9 @@ static int of_aemif_parse_abus_config(struct platform_device *pdev,
struct device_node *np)
{
struct aemif_device *aemif = platform_get_drvdata(pdev);
unsigned long clk_rate = aemif->clk_rate;
struct aemif_cs_data *data;
int ret;
u32 cs;
u32 val;

Expand All @@ -287,26 +275,61 @@ static int of_aemif_parse_abus_config(struct platform_device *pdev,
aemif_get_hw_params(pdev, aemif->num_cs++);

/* override the values from device node */
if (!of_property_read_u32(np, "ti,cs-min-turnaround-ns", &val))
data->ta = val;
if (!of_property_read_u32(np, "ti,cs-min-turnaround-ns", &val)) {
ret = aemif_calc_rate(pdev, val, clk_rate, TA_MAX);
if (ret < 0)
return ret;

if (!of_property_read_u32(np, "ti,cs-read-hold-ns", &val))
data->rhold = val;
data->ta = ret;
}

if (!of_property_read_u32(np, "ti,cs-read-strobe-ns", &val))
data->rstrobe = val;
if (!of_property_read_u32(np, "ti,cs-read-hold-ns", &val)) {
ret = aemif_calc_rate(pdev, val, clk_rate, RHOLD_MAX);
if (ret < 0)
return ret;

if (!of_property_read_u32(np, "ti,cs-read-setup-ns", &val))
data->rsetup = val;
data->rhold = ret;
}

if (!of_property_read_u32(np, "ti,cs-write-hold-ns", &val))
data->whold = val;
if (!of_property_read_u32(np, "ti,cs-read-strobe-ns", &val)) {
ret = aemif_calc_rate(pdev, val, clk_rate, RSTROBE_MAX);
if (ret < 0)
return ret;

if (!of_property_read_u32(np, "ti,cs-write-strobe-ns", &val))
data->wstrobe = val;
data->rstrobe = ret;
}

if (!of_property_read_u32(np, "ti,cs-write-setup-ns", &val))
data->wsetup = val;
if (!of_property_read_u32(np, "ti,cs-read-setup-ns", &val)) {
ret = aemif_calc_rate(pdev, val, clk_rate, RSETUP_MAX);
if (ret < 0)
return ret;

data->rsetup = ret;
}

if (!of_property_read_u32(np, "ti,cs-write-hold-ns", &val)) {
ret = aemif_calc_rate(pdev, val, clk_rate, WHOLD_MAX);
if (ret < 0)
return ret;

data->whold = ret;
}

if (!of_property_read_u32(np, "ti,cs-write-strobe-ns", &val)) {
ret = aemif_calc_rate(pdev, val, clk_rate, WSTROBE_MAX);
if (ret < 0)
return ret;

data->wstrobe = ret;
}

if (!of_property_read_u32(np, "ti,cs-write-setup-ns", &val)) {
ret = aemif_calc_rate(pdev, val, clk_rate, WSETUP_MAX);
if (ret < 0)
return ret;

data->wsetup = ret;
}

if (!of_property_read_u32(np, "ti,cs-bus-width", &val))
if (val == 16)
Expand Down

0 comments on commit 1ec0fa9

Please sign in to comment.