<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>