i.MX28 SOC DMA тайм-аут при чтении NAND FLASH

i.MX28 SOC DMA тайм-аут при чтении NAND FLASH

Я портирую последнее ядро ​​Linux на старое существующее оборудование, такое как набор i.MX28 EVK от Freescale и плата Karo TX28. Я хочу использовать часть NAND FLASH в файловой системе («раздел userfs» в NAND).

Первый шаг — использование ubiattach /dev/ubi_ctrl -m 6. Эта операция пытается найти таблицу томов и считывает чип NAND, несколько операций gpmi_read_page. Это приводит к тайм-ауту DMA в start_dma_without_bch_irq (gpmi-nand.c). Странно то, что первое количество операций read_page завершается успешно. Затем наступает тайм-аут.

Первое впечатление — проблема с синхронизацией. Изменение синхронизации NAND не изменило наблюдаемое поведение. Многочисленные отладки, в основном сосредоточенные на значениях в регистрах GPMI, GPIO и коллектора прерываний, ничего не выявили.

Мне удалось получить некоторые измерительные соединения на линиях управления чипа NAND в плате i.MX28 EVK. Используя логический анализатор Saleae (имитация), я могу увидеть ряд правильных транзакций (в диапазоне 20, 40, что-то около того). Затем устанавливается чтение, сигналы NAND готовы правильно, GPMI запрашивается для чтения данных, и GPMI тактирует данные из NAND, нотерпит неудачудля установки линии включения чипа (низкий уровень активности). Похоже, что GPMI больше не работает правильно внутри. Теперь ISR для сигнализации об окончании операции чтения не вводится (я использовал вторую линию включения чипа, чтобы сигнализировать об этом, отладочный вывод говорит о том же). Отсюда и тайм-аут. Похоже, что GPMI "запутался" внутри.

Я проверил, что мультиплексор выводов для линии включения чипа по-прежнему корректен после тайм-аута. Судя по отладочному выводу, то же самое происходит на Karo TX 28 (измерения на выводах нет, я не смог подключиться).

Я видел старые письма, связанные с проблемами с i.MX23 и сбросом GPMI дважды (U-boot и ядро ​​Linux), что приводило к зависанию GPMI. Эксперименты с этим исправлением не помогли. Проблема наблюдается на ядре Linux 5.0.8 и 4.20.7. Насколько я могу судить, NAND работает правильно при использовании из U-Boot. Я пробовал те же настройки тайминга, что и U-Boot, но безуспешно.

Обратите внимание, что на плате Karo используется Samsung NAND, на i.MX28 EVK — часть от Spansion. Так что это, похоже, не связано с конкретным чипом NAND. Также обратите внимание, что то же самое наблюдается, когда раздел NAND присоединяется из командной строки загрузки Linux в U-boot.

Вопрос в том, что делать, чтобы найти первопричину и возможное решение.

решение1

Сначала я много занимался отладкой, но решения не нашел. Потом я понял, что у меня старая версия Linux, которая работает (она была подготовлена ​​другой компанией много лет назад). Это доказывает, что это не проблема с оборудованием. Также тот факт, что 2 разные аппаратные платы показывают одну и ту же проблему, указывает на то, что это не проблема с оборудованием. В какой-то момент я решил попробовать старую версию Linux, максимально приближенную к старому рабочему решению. Это показало, что ядро ​​3.16.68 работало нормально, используя собственную сборку. Мои сборки 5.1.5 и 4.20.7 показывают проблему NAND FLASH. Дополнительные эксперименты показали, что последнее рабочее ядро ​​— 4.16.18, начиная с 4.17.1 и более поздних версий проблема присутствует. Похоже, что между этим была реструктурирована поддержка NAND FLASH для периферийного устройства Freescale GPMI. Я предполагаю, что это сделано freescale, чтобы приспособиться к новым процессорам / SOC. Похоже, что поддержка старого оборудования сломана. Я не могу сказать, известно ли это в Freescale или нет. Есть признаки того, что Freescale больше не поддерживает старый i.MX28. В любом случае, теперь пришло время проанализировать различия. Решающее различие, по-видимому, заключается в вызове функции для адаптации тактовой частоты периферийного устройства GPMI, которое было добавлено. По какой-то причине после комментирования этого одного вызова периферийное устройство GPMI, похоже, работает правильно с NAND FLASH. Этот код находится в файле "drivers/mtd/nand/raw/gpminand/gpmi-lib.c", функция "gpmi_nfc_apply_timings". Просто закомментируйте вызов "clk_set_rate". По крайней мере, у меня это работает. Позже я понял, что лучше избегать вызова только при процессоре i.MX28, чтобы он работал для более поздних чипов.

Я не анализировал, что именно делает clk_set_rate и как его следует вызывать, чтобы он работал для всех процессоров. У меня нет другого оборудования, поэтому я не смогу это проверить.

Связанный контент