aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xarch/arm/configs/abox_edge_defconfig21
-rw-r--r--arch/arm64/boot/dts/pxa1908-board-common.dtsi58
-rw-r--r--arch/arm64/boot/dts/pxa1908.dtsi33
-rw-r--r--arch/arm64/mach/helanx-dt.c3
-rw-r--r--drivers/clk/mmp/clk-pxa1U88.c3
-rw-r--r--drivers/mtd/devices/m25p80.c1
-rw-r--r--drivers/spi/spi-pxa2xx.c66
-rw-r--r--drivers/spi/spi-pxa2xx.h2
8 files changed, 151 insertions, 36 deletions
diff --git a/arch/arm/configs/abox_edge_defconfig b/arch/arm/configs/abox_edge_defconfig
index 30eacdc78ce..2dc93653b2c 100755
--- a/arch/arm/configs/abox_edge_defconfig
+++ b/arch/arm/configs/abox_edge_defconfig
@@ -316,6 +316,7 @@ CONFIG_ARCH_MMP=y
# CONFIG_GPIO_PCA953X is not set
# CONFIG_KEYBOARD_GPIO_POLLED is not set
# CONFIG_MACH_TAVOREVB is not set
+CONFIG_PXA_SSP=y
#
# Marvell PXA168/910/MMP2 Implmentations
@@ -1046,6 +1047,7 @@ CONFIG_FW_LOADER_USER_HELPER=y
# CONFIG_HAVE_CPU_AUTOPROBE is not set
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_SPI=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGMAP_IRQ=y
CONFIG_DMA_SHARED_BUFFER=y
@@ -1068,7 +1070,14 @@ CONFIG_DYNAMIC_TOPOLOGY_SYSFS=y
#
# CONFIG_ARM_CCI is not set
# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+CONFIG_MTD_M25P80=y
CONFIG_DTC=y
CONFIG_OF=y
@@ -1083,6 +1092,7 @@ CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_NET=y
CONFIG_OF_MDIO=y
+CONFIG_OF_MTD=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
@@ -1307,6 +1317,7 @@ CONFIG_NET_VENDOR_MARVELL=y
CONFIG_NET_VENDOR_MICREL=y
# CONFIG_KS8842 is not set
# CONFIG_KS8851_MLL is not set
+CONFIG_NET_VENDOR_MICROCHIP=y
CONFIG_NET_VENDOR_NATSEMI=y
CONFIG_NET_VENDOR_8390=y
# CONFIG_AX88796 is not set
@@ -1647,7 +1658,11 @@ CONFIG_I2C_PXA=y
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_SPI is not set
+CONFIG_SPI=y
+CONFIG_SPI_DEBUG=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_PXA2XX_DMA=y
+CONFIG_SPI_PXA2XX=y
# CONFIG_HSI is not set
#
@@ -2238,6 +2253,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_MMP_DISP=y
CONFIG_MMP_DISP_CONTROLLER=y
CONFIG_MMP_DISP_DFC=y
+CONFIG_MMP_DISP_SPI=y
# CONFIG_MMP_VIRTUAL_RESOLUTION is not set
# CONFIG_MMP_PANEL_HX8394_IPS3P5071 is not set
CONFIG_MMP_PANEL_R63311=y
@@ -2312,6 +2328,7 @@ CONFIG_SND_DRIVERS=y
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=y
# CONFIG_SND_USB_UA101 is not set
diff --git a/arch/arm64/boot/dts/pxa1908-board-common.dtsi b/arch/arm64/boot/dts/pxa1908-board-common.dtsi
index 5c76d332432..2c0c546e2c8 100644
--- a/arch/arm64/boot/dts/pxa1908-board-common.dtsi
+++ b/arch/arm64/boot/dts/pxa1908-board-common.dtsi
@@ -407,6 +407,7 @@
&range 55 55 0 /* GPIO0 ~ GPIO54 */
&range 110 32 0 /* GPIO67 ~ GPIO98 */
&range 52 1 0 /* GPIO124 */
+ &range 6 1 0 /* GPIO65 */
>;
pinctrl-names = "default";
pinctrl-0 = <&mfp_pins_group_0 &mfp_pins_group_1>;
@@ -426,10 +427,6 @@
mfp_pins_group_0: mfp_pins_group_0 {
pinctrl-single,pins = <
/* DF_IO8 AF0 */
- DF_IO9 AF0
- DF_IO10 AF0
- DF_IO11 AF0
- DF_IO12 AF0
DF_IO13 AF0
DF_IO15 AF0
>;
@@ -650,21 +647,21 @@
};
spi0_pmx_func: spi0_pmx_func {
- pinctrl-single,pins = <
- GPIO33 AF2 /* GPIO33 SSP0_CLK */
- GPIO34 AF2 /* GPIO34 SSP0_FRM */
- GPIO35 AF2 /* GPIO35 SSP0_RX */
- GPIO36 AF2 /* GPIO36 SSP0_TX */
+ pinctrl-single,pins = <
+ GPIO33 AF2 /* GPIO33 SSP0_CLK */
+ GPIO34 AF2 /* GPIO34 SSP0_FRM */
+ GPIO35 AF2 /* GPIO35 SSP0_RX */
+ GPIO36 AF2 /* GPIO36 SSP0_TX */
>;
MFP_DEFAULT;
};
- spi1_pmx_func: spi1_pmx_func {
- pinctrl-single,pins = <
- DF_IO9 AF2 /* GPIO66 SSP2_CLK */
- DF_IO10 AF2 /* GPIO65 SSP2_FRM */
- DF_IO11 AF2 /* GPIO64 SSP2_TX */
- DF_IO12 AF2 /* GPIO63 SSP2_RX */
+ spi2_pmx_func: spi2_pmx_func {
+ pinctrl-single,pins = <
+ DF_IO9 AF2 /* GPIO66 SSP2_CLK */
+ DF_IO10 AF1 /* GPIO65 SSP2_FRM */
+ DF_IO11 AF2 /* GPIO64 SSP2_TX */
+ DF_IO12 AF2 /* GPIO63 SSP2_RX */
>;
MFP_DEFAULT;
};
@@ -1065,6 +1062,37 @@
};
};
+ spi_0: ssp@d401b000 {
+ status = "disabled";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pmx_func>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ spidev {
+ spi-max-frequency = <52000000>;
+ reg = <0>;
+ compatible = "rohm,dh2228fv";
+ status = "okay";
+ };
+ };
+
+ spi_2: ssp@d401c000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pmx_func>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ flash: m25p80@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sst,sst25wf040b";
+ spi-max-frequency = <40000000>;
+ reg = <0>;
+ };
+ };
+
/* SSPA port 0 */
sspa0: sspa@d128dc00 {
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/pxa1908.dtsi b/arch/arm64/boot/dts/pxa1908.dtsi
index dd9a824f6f8..987bff725fe 100644
--- a/arch/arm64/boot/dts/pxa1908.dtsi
+++ b/arch/arm64/boot/dts/pxa1908.dtsi
@@ -601,7 +601,7 @@
gcb2: gpio@d4019008 {
reg-offset = <0x8>;
- gpio-ranges = <&pmx 3 110 29>;
+ gpio-ranges = <&pmx 1 6 1 &pmx 3 110 29>;
};
gcb3: gpio@d4019100 {
@@ -633,6 +633,37 @@
status = "disabled";
};
+ spi_0: ssp@d401b000 {
+ compatible = "marvell,pxa910-spi";
+ marvell,ssp-enhancement;
+ reg = <0xd401b000 0x90>;
+ ssp-id = <0>;
+ interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>;
+ /* dma engineer, DRCMR offset, user_do_qos */
+ dmas = <&pdma0 52 1
+ &pdma0 53 1>;
+ dma-names = "rx", "tx";
+ lpm-qos = <PM_QOS_CPUIDLE_BLOCK_AXI>;
+ clocks = <&soc_clocks PXA1U88_CLK_SSP0>;
+ status = "disabled";
+ };
+
+ spi_2: ssp@d401c000 {
+ compatible = "marvell,pxa910-spi";
+ marvell,ssp-enhancement;
+ marvell,ssp-nor-flash;
+ reg = <0xd401c000 0x90>;
+ ssp-id = <2>;
+ interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&pdma0 60 1
+ &pdma0 61 1>;
+ dma-names = "rx", "tx";
+ lpm-qos = <PM_QOS_CPUIDLE_BLOCK_AXI>;
+ clocks = <&soc_clocks PXA1U88_CLK_SSP2>;
+ cs-gpios = <&gpio 65 0>;
+ status = "disabled";
+ };
+
sspa0: sspa@d128dc00 {
compatible = "mrvl,mmp-sspa-dai";
reg = <0xd128dc00 0x100>;
diff --git a/arch/arm64/mach/helanx-dt.c b/arch/arm64/mach/helanx-dt.c
index 2f0b5bcccc0..80939cee0f0 100644
--- a/arch/arm64/mach/helanx-dt.c
+++ b/arch/arm64/mach/helanx-dt.c
@@ -68,6 +68,9 @@ static const struct of_dev_auxdata helanx_auxdata_lookup[] __initconst = {
OF_DEV_AUXDATA("regulator-leds", 0, "leds-regulator",
&keypad_backlight),
#endif
+#ifdef CONFIG_SPI_PXA2XX
+ OF_DEV_AUXDATA("marvell,pxa910-spi", 0xd401c000, "pxa910-ssp.2", NULL),
+#endif
{}
};
diff --git a/drivers/clk/mmp/clk-pxa1U88.c b/drivers/clk/mmp/clk-pxa1U88.c
index 48d825beb81..7475a04decf 100644
--- a/drivers/clk/mmp/clk-pxa1U88.c
+++ b/drivers/clk/mmp/clk-pxa1U88.c
@@ -519,7 +519,7 @@ static void pxa1U88_apb_periph_clk_init(struct pxa1U88_clk_unit *pxa_unit)
ARRAY_SIZE(ssp_parent_names), 0,
pxa_unit->apbc_base + APBC_SSP2, 4, 3, 0, NULL);
clk = mmp_clk_register_gate(NULL, "ssp2_clk", "ssp2_mux",
- 0,
+ CLK_SET_RATE_PARENT | CLK_SET_RATE_ENABLED,
pxa_unit->apbc_base + APBC_SSP2,
0x7, 0x3, 0x0, 0, NULL);
mmp_clk_add(unit, PXA1U88_CLK_SSP2, clk);
@@ -1494,7 +1494,6 @@ static void __init pxa1U88_misc_init(struct pxa1U88_clk_unit *pxa_unit)
val = __raw_readl(pxa_unit->apmu_base + APMU_DVC_DFC_DEBUG);
val |= (1 << 5);
__raw_writel(val, pxa_unit->apmu_base + APMU_DVC_DFC_DEBUG);
-
}
static void __init pxa1U88_clk_init(struct device_node *np)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index ad191390970..4a7c796379d 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -977,6 +977,7 @@ static const struct spi_device_id m25p_ids[] = {
{ "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) },
{ "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) },
{ "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) },
+ { "sst25wf040b", INFO(0x621613, 0, 64 * 1024, 8, SECT_4K) },
{ "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) },
/* ST Microelectronics -- newer production may have feature updates */
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 98eca261273..b37f657fb7d 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -593,8 +593,9 @@ static irqreturn_t pxa2xx_spi_int(int irq, void *dev_id)
return IRQ_NONE;
if (!drv_data->cur_msg) {
-
+ /* Disable SSPx port */
write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
+ /* Disable TXFIFO/RXFIFO/RX-Timeout interrupt */
write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
if (!pxa25x_ssp_comp(drv_data))
write_SSTO(0, reg);
@@ -777,8 +778,10 @@ static void pump_transfers(unsigned long data)
SSCR2_RD_ENDIAN_16BITS;
bits = 32;
drv_data->n_bytes = 4;
- drv_data->read = u32_reader;
- drv_data->write = u32_writer;
+ drv_data->read = drv_data->read != null_reader ?
+ u32_reader : null_reader;
+ drv_data->write = drv_data->write != null_writer ?
+ u32_writer : null_writer;
if (chip->enable_dma) {
if (pxa2xx_spi_set_dma_burst_and_threshold(chip,
@@ -802,7 +805,6 @@ static void pump_transfers(unsigned long data)
if (pxa2xx_spi_dma_is_possible(drv_data->len))
drv_data->dma_mapped = pxa2xx_spi_map_dma_buffers(drv_data);
if (drv_data->dma_mapped) {
-
/* Ensure we have the correct interrupt handler */
drv_data->transfer_handler = pxa2xx_spi_dma_transfer;
@@ -829,6 +831,7 @@ static void pump_transfers(unsigned long data)
write_SSITF(chip->lpss_tx_threshold, reg);
}
+
/* see if we need to reload the config registers */
if ((read_SSCR0(reg) != cr0)
|| (read_SSCR1(reg) & SSCR1_CHANGE_MASK) !=
@@ -933,6 +936,7 @@ static int setup(struct spi_device *spi)
struct driver_data *drv_data = spi_master_get_devdata(spi->master);
unsigned int clk_div;
uint tx_thres, tx_hi_thres, rx_thres;
+ int ret = 0;
if (is_lpss_ssp(drv_data)) {
tx_thres = LPSS_TX_LOTHRESH_DFLT;
@@ -961,10 +965,14 @@ static int setup(struct spi_device *spi)
kfree(chip);
return -EINVAL;
}
-
chip->frm = spi->chip_select;
- } else
+ } else if (drv_data->ssp_nor_flash) {
+ chip->gpio_cs = spi->cs_gpio;
+ chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH;
+ }
+ else
chip->gpio_cs = -1;
+
chip->enable_dma = 0;
chip->timeout = TIMOUT_DFLT;
}
@@ -1013,8 +1021,13 @@ static int setup(struct spi_device *spi)
}
}
- /* clk_div represent to Bit17-8 bits of CS0 */
+ /* clk_div represent to Bit19-8 bits of CS0 */
clk_div = ssp_get_clk_div(drv_data, spi->max_speed_hz);
+
+ /* Clock rate setting not in SSCR0 for Marvell SSP2 */
+ if (drv_data->ssp_nor_flash)
+ clk_set_rate(drv_data->clk, spi->max_speed_hz);
+
chip->speed_hz = spi->max_speed_hz;
chip->cr0 = clk_div
@@ -1030,8 +1043,12 @@ static int setup(struct spi_device *spi)
if (spi->mode & SPI_LOOP)
chip->cr1 |= SSCR1_LBM;
+ if (drv_data->ssp_nor_flash)
+ dev_dbg(&spi->dev, "%ld Hz actual, %s\n",
+ clk_get_rate(drv_data->clk),
+ chip->enable_dma ? "DMA" : "PIO");
/* NOTE: PXA25x_SSP _could_ use external clocking ... */
- if (!pxa25x_ssp_comp(drv_data))
+ else if (!pxa25x_ssp_comp(drv_data))
dev_dbg(&spi->dev, "%ld Hz actual, %s\n",
drv_data->max_clk_rate
/ (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)),
@@ -1042,7 +1059,6 @@ static int setup(struct spi_device *spi)
/ (1 + ((chip->cr0 & SSCR0_SCR(0x0ff)) >> 8)),
chip->enable_dma ? "DMA" : "PIO");
-
/* Enable rx fifo auto full control */
if (drv_data->ssp_enhancement)
chip->cr2 = SSCR2_RX_FULL_CTRL;
@@ -1066,7 +1082,21 @@ static int setup(struct spi_device *spi)
spi_set_ctldata(spi, chip);
if (drv_data->ssp_type == CE4100_SSP)
- return 0;
+ return ret;
+
+ /* Configure SSP2_FRM as GPIO for SPI #CS */
+ if (drv_data->ssp_nor_flash && gpio_is_valid(chip->gpio_cs)) {
+ ret = gpio_request(chip->gpio_cs, dev_name(&spi->dev));
+ if (ret) {
+ dev_err(&spi->dev, "failed to request chip select GPIO%d\n",
+ chip->gpio_cs);
+ return ret;
+ }
+
+ ret = gpio_direction_output(chip->gpio_cs,
+ !chip->gpio_cs_inverted);
+ return ret;
+ }
return setup_cs(spi, chip, chip_info);
}
@@ -1228,6 +1258,11 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
/* Receive FIFO auto full ctrl enable */
if (of_get_property(np, "marvell,ssp-enhancement", NULL))
drv_data->ssp_enhancement = 1;
+
+ /* Use SSP2 port for SPI Nor flash */
+ if (of_get_property(np, "marvell,ssp-nor-flash", NULL))
+ drv_data->ssp_nor_flash = 1;
+
/*
* the null DMA buf should malloc form DMA_ZONE
* and align of DMA_ALIGNMENT
@@ -1267,7 +1302,6 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
master->bus_num = bus_num;
drv_data->ssdr_physical = iores->start + SSDR;
drv_data->clk = devm_clk_get(dev, NULL);
-
#else
ssp = pxa_ssp_request(pdev->id, pdev->name);
if (!ssp)
@@ -1356,6 +1390,11 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
tasklet_init(&drv_data->pump_transfers, pump_transfers,
(unsigned long)drv_data);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
/* Register with the SPI framework */
platform_set_drvdata(pdev, drv_data);
status = devm_spi_register_master(&pdev->dev, master);
@@ -1364,11 +1403,6 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
goto out_error_clock_enabled;
}
- pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
- pm_runtime_use_autosuspend(&pdev->dev);
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
-
return status;
out_error_clock_enabled:
diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h
index 3c9788acd9e..7fa576a0bf8 100644
--- a/drivers/spi/spi-pxa2xx.h
+++ b/drivers/spi/spi-pxa2xx.h
@@ -98,6 +98,8 @@ struct driver_data {
int irq;
/* Support RX FIFO auto full control and endian swap */
unsigned int ssp_enhancement;
+ /* Use SSP2 for SPI Nor flash chip */
+ unsigned int ssp_nor_flash;
#endif
};