diff options
-rwxr-xr-x | arch/arm/configs/abox_edge_defconfig | 21 | ||||
-rw-r--r-- | arch/arm64/boot/dts/pxa1908-board-common.dtsi | 58 | ||||
-rw-r--r-- | arch/arm64/boot/dts/pxa1908.dtsi | 33 | ||||
-rw-r--r-- | arch/arm64/mach/helanx-dt.c | 3 | ||||
-rw-r--r-- | drivers/clk/mmp/clk-pxa1U88.c | 3 | ||||
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 1 | ||||
-rw-r--r-- | drivers/spi/spi-pxa2xx.c | 66 | ||||
-rw-r--r-- | drivers/spi/spi-pxa2xx.h | 2 |
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 }; |