(PATCH) i.MX233 SSP2 working in hardware mode through SPIDEV (kernel 2.6.35.3)

Started by scout_3pm, May 25, 2013, 07:05:03 PM

Previous topic - Next topic

scout_3pm

Hi to all.
Here I will post two patches, which add SSP2 configuration to kernel-2.6.35.3. SSP2 then is used through spidev driver. I.e SSP2 is now working in hardware mode, not bitbang.
[the kernel 2.6.35.3 is from latest FSL-Yocto-BSP (denzil branch) ]


As I bought iMX233-OLinuXino-MAXI I had no idea that the SPI port on UEXT is not working in hardware mode.
But exactly that feature I need. So for the past two days I was struggling with the SSP2 proper configuration
in arch/arm/mach-mx23 and binding it with spidev. This is the result.

Please test to verify it is working :-)
------------------------------------

Here are the two patches:

First sets the SSP2 configuration


diff -crB arch/arm/mach-mx23/device.c arch/arm/mach-mx23.new/device.c
*** arch/arm/mach-mx23/device.c 2013-05-25 18:35:28.000000000 +0300
--- arch/arm/mach-mx23.new/device.c 2013-05-25 18:38:15.000000000 +0300
***************
*** 673,681 ****
 
  #if defined(CONFIG_SPI_MXS) || defined(CONFIG_SPI_MXS_MODULE)
  static struct mxs_spi_platform_data ssp1_data = {
- .hw_pin_init = mxs_spi_enc_pin_init,
- .hw_pin_release = mxs_spi_enc_pin_release,
  .clk = "ssp.0",
  };
 
  static struct resource ssp1_resources[] = {
--- 673,685 ----
 
  #if defined(CONFIG_SPI_MXS) || defined(CONFIG_SPI_MXS_MODULE)
  static struct mxs_spi_platform_data ssp1_data = {
  .clk = "ssp.0",
+ .slave_mode = 0,
+ };
+
+ static struct mxs_spi_platform_data ssp2_data = {
+ .clk = "ssp.0",
+ .slave_mode = 0,
  };
 
  static struct resource ssp1_resources[] = {
***************
*** 698,703 ****
--- 702,727 ----
  },
  };
 
+ static struct resource ssp2_resources[] = {
+ {
+ .start = SSP2_PHYS_ADDR,
+ .end = SSP2_PHYS_ADDR + 0x1FFF,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_SSP2_DMA,
+ .end = IRQ_SSP2_DMA,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_SSP2_ERROR,
+ .end = IRQ_SSP2_ERROR,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = MXS_DMA_CHANNEL_AHB_APBH_SSP2,
+ .end = MXS_DMA_CHANNEL_AHB_APBH_SSP2,
+ .flags = IORESOURCE_DMA,
+ },
+ };
+
  static void __init mx23_init_spi1(void)
  {
  struct platform_device *pdev;
***************
*** 711,721 ****
--- 735,764 ----
 
  mxs_add_device(pdev, 3);
  }
+
+ static void __init mx23_init_spi2(void)
+ {
+ struct platform_device *pdev;
+
+ pdev = mxs_get_device("mxs-spi", 0);
+ if (pdev == NULL || IS_ERR(pdev))
+ return;
+ pdev->resource = ssp2_resources;
+ pdev->num_resources = ARRAY_SIZE(ssp2_resources);
+ pdev->dev.platform_data = &ssp2_data;
+
+ mxs_add_device(pdev, 3);
+ }
  #else
  static void mx23_init_spi1(void)
  {
  ;
  }
+
+ static void mx23_init_spi2(void)
+ {
+ ;
+ }
  #endif
 
  #define CMDLINE_DEVICE_CHOOSE(name, dev1, dev2) \
***************
*** 995,1000 ****
--- 1038,1044 ----
  mx23_init_ts();
  mx23_init_rtc();
  mx23_init_dcp();
+ mx23_init_spi2();
  mx23_init_ssp1();
  mx23_init_gpmi_nfc();
  mx23_init_spdif();
diff -crB arch/arm/mach-mx23/imx233_olinuxino.c arch/arm/mach-mx23.new/imx233_olinuxino.c
*** arch/arm/mach-mx23/imx233_olinuxino.c 2013-05-25 18:35:28.000000000 +0300
--- arch/arm/mach-mx23.new/imx233_olinuxino.c 2013-05-25 18:38:15.000000000 +0300
***************
*** 44,49 ****
--- 44,66 ----
  mx23_set_input_clk(24000000, 24000000, 32000, 50000000);
  }
 
+ static struct spi_board_info spi_board_info[] __initdata = {
+ #if defined(CONFIG_SPI_MXS) || defined(CONFIG_SPI_MXS_MODULE)
+         {
+                 /* the modalias must be the same as spi device driver name */
+                 .modalias = "spidev", /* Name of spi_driver for this device */
+                 .max_speed_hz = 48000000,     /* max spi clock (SCK) speed in HZ */
+                 .bus_num = 1, /* Framework bus number */
+                 .chip_select = 0, /* Framework chip select. */
+         },
+ #endif
+ };
+
+ static void spi_device_init(void)
+ {
+         spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ }
+
  #if defined(CONFIG_SND_MXS_SOC_ADC) || defined(CONFIG_SND_MXS_SOC_ADC_MODULE)
  static void __init imx233_olinuxino_init_adc(void)
  {
***************
*** 63,68 ****
--- 80,86 ----
  static void __init imx233_olinuxino_device_init(void)
  {
  imx233_olinuxino_init_adc();
+ spi_device_init();
  }
 
 
diff -crB arch/arm/mach-mx23/imx233_olinuxino_pins.c arch/arm/mach-mx23.new/imx233_olinuxino_pins.c
*** arch/arm/mach-mx23/imx233_olinuxino_pins.c 2013-05-25 18:35:28.000000000 +0300
--- arch/arm/mach-mx23.new/imx233_olinuxino_pins.c 2013-05-25 18:42:17.000000000 +0300
***************
*** 335,360 ****
  {
  .name = "UEXT.9",
  .id = PINID_GPMI_WRN,
! .fun = PIN_GPIO,
! .strength = PAD_12MA,
! .voltage = PAD_3_3V,
! .drive = 1,
  },
  {
  .name = "UEXT.10",
! .id = PINID_GPMI_RDY0,
! .fun = PIN_GPIO,
! .strength = PAD_12MA,
! .voltage = PAD_3_3V,
! .drive = 1,
  },
  {
  .name = "UEXT.8",
  .id = PINID_GPMI_RDY1,
! .fun = PIN_GPIO,
! .strength = PAD_12MA,
! .voltage = PAD_3_3V,
! .drive = 1,
  },
  {
  .name = "GPIO.04",
--- 335,356 ----
  {
  .name = "UEXT.9",
  .id = PINID_GPMI_WRN,
! .fun = PIN_FUN3,
  },
  {
  .name = "UEXT.10",
! .id = PINID_GPMI_D03,
! .fun = PIN_FUN3,
  },
  {
  .name = "UEXT.8",
  .id = PINID_GPMI_RDY1,
! .fun = PIN_FUN3,
! },
! {
! .name = "UEXT.7",
! .id = PINID_GPMI_D00,
! .fun = PIN_FUN3,
  },
  {
  .name = "GPIO.04",
***************
*** 428,441 ****
  .fun = PIN_GPIO,
  .strength = PAD_12MA,
  .voltage = PAD_3_3V,
- .drive = 1,
- },
- {
- .name = "GPIO.19",
- .id = PINID_GPMI_D00,
- .fun = PIN_GPIO,
- .strength = PAD_12MA,
- .voltage = PAD_3_3V,
  .drive = 1,
  },
  {
--- 424,429 ----



Second sets the correct max SSPCLK for the spi_mxs driver


*** drivers/spi/spi_mxs.c 2013-05-25 16:43:00.000000000 +0300
--- drivers/spi.new/spi_mxs.c 2013-05-25 16:46:06.000000000 +0300
***************
*** 619,625 ****
  goto out_free_dma_desc;
  }
 
! clk_set_rate(ss->clk, 120 * 1000 * 1000);
  ss->speed_khz = clk_get_rate(ss->clk) / 1000;
  ss->divider = 2;
  dev_info(&dev->dev, "Max possible speed %d = %ld/%d kHz\n",
--- 619,626 ----
  goto out_free_dma_desc;
  }
 
! /* MAX SSPCLK for i.MX28 is 120Mhz , but for i.MX23 it is 96Mhz */
! clk_set_rate(ss->clk, 96 * 1000 * 1000);
  ss->speed_khz = clk_get_rate(ss->clk) / 1000;
  ss->divider = 2;
  dev_info(&dev->dev, "Max possible speed %d = %ld/%d kHz\n",



You must be inside KERNEL SOURCE ROOT to apply the patches with the following commands

patch -p0 -i add-ssp2-configuration.patch

patch -p0 -i fix-sspclk-for-imx233.patch

------------------------------------

Then in your kernel config mark the following:

SPI Support - CONFIG_SPI = y

Freescale MXS SPI/SSP controller - CONFIG_SPI_MXS = y

User mode SPI device driver support - CONFIG_SPI_SPIDEV = y


And now for the bad news - for some reason after SPI_MXS driver is builtin the RTC stall the kernel boot process
for several minutes with no apparent reason. I will continue to look at this and try to figure it out, but for now in
your kernel config you have to give NO to setting system time from rtc on startup and resume, if you want normal as time
boot process:

Real Time Clock -> Set System Time from RTC on startup and resume - CONFIG_RTC_HCTOSYS = n

------------------------------------

If you want to build SPI_MXS driver as module you will get error at compile time.
I found the following patch (fixing the issue)
Note: when SPI_MXS driver is as module the boot process is normal (no need to disable RTC set on startup),
because modules are loaded at later time, after rtc setting is passed.

https://community.freescale.com/thread/300251

----

jeroends


scout_3pm

Well, i'm glad you appreciate my work :-) It have been two long days.

Now for the patch you give:
1. It is for 3.x kernel.
2. Is about fixing issue with incorrect transfer size when dma is used.

I don't see how this apply here.
If you see a DMA misconfiguration in the spi_mxs driver in kernel 2.6.35.3, please point it out.

I took a little time to check the driver and it is ok, it just had missing SSP2 configuration and wrong SSPCLK set.
Still I haven't made some real testing so I'm looking forward somebody with SPI hardware/UEXT modules to check and share the outcome. :-)

Maybe you are giving this patch with the idea why I do not use kernel 3.x , well because 2.6 looks more stable and have some feautures which still are missing in 3.x as far as i know.

PS: Now I'm choosing what kind of rootfs to use for my needs, Debian, ArchLinux or from YOCTO/OE build.