i.MX28 SOC DMA tiempo de espera al leer NAND FLASH

i.MX28 SOC DMA tiempo de espera al leer NAND FLASH

Estoy portando el kernel de Linux reciente a hardware existente más antiguo, como el kit i.MX28 EVK de Freescale y la placa Karo TX28. Quiero usar una parte de NAND FLASH en el sistema de archivos ("partición userfs" en NAND).

El primer paso es usar ubiattach /dev/ubi_ctrl -m 6. Esta operación intenta encontrar una tabla de volúmenes y lee el chip NAND, una serie de operaciones gpmi_read_page. Esto provoca un tiempo de espera de DMA en start_dma_ without_bch_irq (gpmi-nand.c). Lo extraño es que el primer número de operaciones read_page tiene éxito. Entonces llega un tiempo muerto.

La primera impresión fue una cuestión de tiempo. Cambiar la sincronización NAND no cambió el comportamiento observado. Mucha depuración, centrada principalmente en los valores en los registros de GPMI, GPIO y el colector de interrupciones, no reveló nada.

Logré obtener algunas conexiones de medición en las líneas de control del chip NAND en la placa i.MX28 EVK. Usando un analizador lógico Saleae (imitación), puedo ver una cantidad de transacciones correctas (en el rango de 20, 40, algo así). Luego se configura una lectura, las señales NAND están listas correctamente, se le pide a la GPMI que lea los datos y la GPMI registra los datos fuera de la NAND, perofallapara configurar la línea de habilitación del chip (activa baja). Parece que el GPMI ya no funciona correctamente internamente. Ahora no se ingresa el ISR para señalar el final de la operación de lectura (usé la línea de habilitación del segundo chip para señalar eso, la salida de depuración cuenta la misma historia). De ahí el tiempo de espera. Parece que el GPMI está "confundido" internamente.

Verifiqué que el multiplexor de pines para la línea de habilitación del chip siga siendo correcto después del tiempo de espera. A juzgar por la salida de depuración, sucede lo mismo en el Karo TX 28 (no hay mediciones en los pines, no pude conectarme).

He visto correos antiguos relacionados con problemas con i.MX23 y el restablecimiento de GPMI dos veces (U-boot y kernel de Linux), lo que provocó que GPMI se colgara. Jugar con esa solución no cambió. El problema se observa en los kernels de Linux 5.0.8 y 4.20.7. Hasta donde puedo juzgar, la NAND funciona correctamente cuando se usa desde U-Boot. Probé la misma configuración de sincronización que usa U-Boot, pero no tuve suerte.

Tenga en cuenta también que en la placa Karo se utiliza una NAND de Samsung, en la i.MX28 EVK una parte de Spansion. Por lo tanto, no parece estar relacionado con el chip NAND en particular. También tenga en cuenta que se observa lo mismo cuando la partición NAND se adjunta desde la línea de comando de arranque de Linux en U-boot.

La pregunta es qué hacer para encontrar la causa raíz y su posible solución.

Respuesta1

Primero, he estado depurando mucho y no encontré ninguna solución. Luego me di cuenta de que tengo una versión antigua de Linux que está funcionando (fue preparada por otra empresa hace años). Eso demuestra que no es un problema de hardware. Además, el hecho de que 2 placas de hardware diferentes muestren el mismo problema no indica que se trate de un problema de hardware. En algún momento decidí probar una versión antigua de Linux, lo más parecida posible a la antigua solución funcional. Eso demostró que el kernel 3.16.68 estaba funcionando bien, usando una compilación propia. Mis versiones 5.1.5 y 4.20.7 muestran el problema NAND FLASH. Más experimentos revelaron que el último kernel en funcionamiento es el 4.16.18, desde el 4.17.1 y posteriores el problema está presente. Parece que en el medio se ha reestructurado el soporte NAND FLASH para el periférico GPMI de Freescale. Supongo que eso lo hace Freescale, para adaptarse a procesadores/SOC más nuevos. Parece que el soporte para el hardware antiguo está roto. No puedo decir si Freescale lo sabe o no. Hay indicios de que Freescale ya no admite el antiguo i.MX28. De todos modos, ahora tocaba analizar diferencias. La diferencia crucial aparece en la llamada a una función para adaptar la frecuencia de reloj del periférico GPMI que se agregó. Por alguna razón, después de comentar esta única llamada, el periférico GPMI parece funcionar correctamente con NAND FLASH. Este código reside en el archivo "drivers/mtd/nand/raw/gpminand/gpmi-lib.c", función "gpmi_nfc_apply_timings". Simplemente comente la llamada a "clk_set_rate". Al menos para mí esto funciona. Más tarde me di cuenta de que sería mejor evitar la llamada sólo cuando el procesador sea i.MX28, para permitir que funcione con chips posteriores.

No analicé qué hace exactamente clk_set_rate y cómo se debe invocar para que funcione en todos los procesadores. No tengo otro hardware, por lo que no podría comprobarlo.

información relacionada