<div dir="ltr"><div dir="ltr"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div style="color:rgb(34,34,34);font-size:medium;font-family:Helvetica;line-height:11px">Verified for its working.</div><div style="color:rgb(34,34,34);font-size:medium;font-family:Helvetica;line-height:11px">Thanks</div><div style="color:rgb(34,34,34);font-size:medium;font-family:Helvetica;line-height:11px"><br></div><div style="color:rgb(34,34,34);font-size:medium;font-family:Helvetica;line-height:11px"><br></div></div></div></div></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 28 Jun 2022 at 21:51, Cédric Le Goater <<a href="mailto:clg@kaod.org">clg@kaod.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">"ranges" predefines settings of the decoding ranges for each CS. If<br>
found in the DT, the driver applies the settings at probe time. The<br>
default behavior is to set the decoding range of each CS using the<br>
flash device size when the spi slave is setup.<br>
<br>
Cc: Naresh Solanki <<a href="mailto:naresh.solanki@9elements.com" target="_blank">naresh.solanki@9elements.com</a>><br>
Cc: Chin-Ting Kuo <<a href="mailto:chin-ting_kuo@aspeedtech.com" target="_blank">chin-ting_kuo@aspeedtech.com</a>><br>
Signed-off-by: Cédric Le Goater <<a href="mailto:clg@kaod.org" target="_blank">clg@kaod.org</a>><br>
---<br>
 drivers/spi/spi-aspeed-smc.c | 63 +++++++++++++++++++++++++++++++++++-<br>
 1 file changed, 62 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c<br>
index 1611c354c31f..791cbf753a85 100644<br>
--- a/drivers/spi/spi-aspeed-smc.c<br>
+++ b/drivers/spi/spi-aspeed-smc.c<br>
@@ -101,6 +101,7 @@ struct aspeed_spi {<br>
        u32                      clk_freq;<br>
<br>
        struct aspeed_spi_chip   chips[ASPEED_SPI_MAX_NUM_CS];<br>
+       bool                     fixed_windows;<br>
 };<br>
<br>
 static u32 aspeed_spi_get_io_mode(const struct spi_mem_op *op)<br>
@@ -574,7 +575,8 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)<br>
        if (op->data.dir != SPI_MEM_DATA_IN)<br>
                return -EOPNOTSUPP;<br>
<br>
-       aspeed_spi_chip_adjust_window(chip, desc->info.offset, desc->info.length);<br>
+       if (!aspi->fixed_windows)<br>
+               aspeed_spi_chip_adjust_window(chip, desc->info.offset, desc->info.length);<br>
<br>
        if (desc->info.length > chip->ahb_window_size)<br>
                dev_warn(aspi->dev, "CE%d window (%dMB) too small for mapping",<br>
@@ -749,6 +751,61 @@ static const struct attribute_group aspeed_spi_attribute_group = {<br>
        .attrs = aspeed_spi_attributes<br>
 };<br>
<br>
+static int aspeed_spi_chip_read_ranges(struct device_node *node, struct aspeed_spi *aspi)<br>
+{<br>
+       const char *range_prop = "ranges";<br>
+       struct property *prop;<br>
+       struct aspeed_spi_window ranges[ASPEED_SPI_MAX_NUM_CS];<br>
+       int prop_size;<br>
+       int count;<br>
+       int ret;<br>
+       int i;<br>
+<br>
+       prop = of_find_property(node, range_prop, &prop_size);<br>
+       if (!prop)<br>
+               return 0;<br>
+<br>
+       count = prop_size / sizeof(*ranges);<br>
+       if (count > aspi->data->max_cs) {<br>
+               dev_err(aspi->dev, "invalid '%s' property %d\n", range_prop, count);<br>
+               return -EINVAL;<br>
+       }<br>
+<br>
+       if (count < aspi->data->max_cs)<br>
+               dev_dbg(aspi->dev, "'%s' property does not cover all CE\n",<br>
+                       range_prop);<br>
+<br>
+       ret = of_property_read_u32_array(node, range_prop, (u32 *)ranges, count * 4);<br>
+       if (ret)<br>
+               return ret;<br>
+<br>
+       dev_info(aspi->dev, "Using preset decoding ranges\n");<br>
+       for (i = 0; i < count; i++) {<br>
+               struct aspeed_spi_window *win = &ranges[i];<br>
+<br>
+               if (win->cs > aspi->data->max_cs) {<br>
+                       dev_err(aspi->dev, "CE%d range is invalid", win->cs);<br>
+                       return -EINVAL;<br>
+               }<br>
+<br>
+               /* Trim top bit of the address to keep offset */<br>
+               win->offset &= aspi->ahb_window_size - 1;<br>
+<br>
+               /* Minimal check */<br>
+               if (win->offset + win->size > aspi->ahb_window_size) {<br>
+                       dev_warn(aspi->dev, "CE%d range is too large", win->cs);<br>
+                               return -EINVAL;<br>
+               }<br>
+<br>
+               ret = aspeed_spi_set_window(aspi, win);<br>
+               if (ret)<br>
+                       return ret;<br>
+       }<br>
+<br>
+       aspi->fixed_windows = true;<br>
+       return 0;<br>
+}<br>
+<br>
 static int aspeed_spi_probe(struct platform_device *pdev)<br>
 {<br>
        struct device *dev = &pdev->dev;<br>
@@ -806,6 +863,10 @@ static int aspeed_spi_probe(struct platform_device *pdev)<br>
                return ret;<br>
        }<br>
<br>
+       ret = aspeed_spi_chip_read_ranges(dev->of_node, aspi);<br>
+       if (ret)<br>
+               return ret;<br>
+<br>
        /* IRQ is for DMA, which the driver doesn't support yet */<br>
<br>
        ctlr->mode_bits = SPI_RX_DUAL | SPI_TX_DUAL | data->mode_bits;<br>
-- <br>
2.35.3<br>
<br>
</blockquote></div></div>