Tempo limite do i.MX28 SOC DMA na leitura do NAND FLASH

Tempo limite do i.MX28 SOC DMA na leitura do NAND FLASH

Estou portando o kernel Linux recente para hardware existente mais antigo, como o kit i.MX28 EVK da Freescale e a placa Karo TX28. Quero usar uma parte do NAND FLASH no sistema de arquivos ("partição userfs" no NAND).

O primeiro passo é usar ubiattach /dev/ubi_ctrl -m 6. Esta operação tenta encontrar uma tabela de volume e lê o chip NAND, uma série de operações gpmi_read_page. Isso leva a um tempo limite de DMA em start_dma_without_bch_irq (gpmi-nand.c). O estranho é que o primeiro número de operações read_page foi bem-sucedido. Então chega um tempo limite.

A primeira impressão foi uma questão de tempo. Alterar o tempo NAND não alterou o comportamento observado. Muita depuração, focada principalmente nos valores dos registros do GPMI, GPIO e coletor de interrupções, não revelou nada.

Consegui algumas conexões de medição nas linhas de controle do chip NAND na placa i.MX28 EVK. Usando um analisador lógico Saleae (imitação), posso ver uma série de transações corretas (na faixa de 20, 40, algo assim). Em seguida, uma leitura é configurada, os sinais NAND estão prontos e corretos, o GPMI é solicitado a ler os dados e o GPMI cronometra os dados para fora do NAND, masfalharpara definir a linha de habilitação do chip (ativa baixa). Parece que o GPMI não está mais funcionando corretamente internamente. Agora o ISR para sinalizar o fim da operação de leitura não foi inserido (usei a segunda linha de habilitação do chip para sinalizar isso, a saída de depuração conta a mesma história). Daí o tempo limite. Parece que o GPMI está "confuso" internamente.

Verifiquei se o multiplexador de pinos da linha de habilitação do chip ainda está correto após o tempo limite. A julgar pela saída de depuração o mesmo acontece no Karo TX 28 (sem medição nos pinos, não consegui conectar).

Tenho visto correspondências antigas relacionadas a problemas com o i.MX23 e à redefinição do GPMI duas vezes (U-boot e kernel do Linux), fazendo com que o GPMI desligasse. Brincar com essa correção não mudou. O problema é observado no kernel Linux 5.0.8 e 4.20.7. Pelo que posso julgar, o NAND funciona corretamente quando usado no U-Boot. Tentei a mesma configuração de tempo que o U-Boot usa, sem sorte.

Observe também que na placa Karo é usado um Samsung NAND, no i.MX28 EVK uma parte do Spansion. Portanto, parece não estar relacionado ao chip NAND específico. Observe também que o mesmo é observado quando a partição NAND é anexada a partir da linha de comando de inicialização do Linux no U-boot.

A questão é o que fazer para encontrar a causa raiz e uma possível correção.

Responder1

Primeiro tenho feito muita depuração, nenhuma solução encontrada. Aí percebi que tenho uma versão antiga do Linux que está funcionando (foi preparada por outra empresa, anos atrás). Isso prova que não é um problema de hardware. Além disso, o fato de duas placas de hardware diferentes apresentarem o mesmo problema não indica um problema de hardware. Em algum momento decidi experimentar uma versão antiga do Linux, o mais próximo possível da antiga solução funcional. Isso mostrou que o kernel 3.16.68 estava funcionando bem, usando uma compilação própria. Minhas compilações 5.1.5 e 4.20.7 mostram o problema NAND FLASH. Mais experimentos revelaram que o último kernel funcional é o 4.16.18, do 4.17.1 e posteriores o problema está presente. Parece que o suporte NAND FLASH para o periférico Freescale GPMI foi reestruturado. Presumo que isso seja feito em freescale, para acomodar processadores/SOCs mais novos. Parece que o suporte para o hardware antigo está quebrado. Não sei dizer se isso é conhecido na Freescale ou não. Há sinais de que o freescale não suporta mais o antigo i.MX28. Enfim, agora era hora de analisar as diferenças. A diferença crucial parece ser uma chamada de função para adaptar a frequência do clock do periférico GPMI que foi adicionado. Por alguma razão, depois de comentar esta única chamada, o periférico GPMI parece funcionar corretamente com o NAND FLASH. Este código reside no arquivo "drivers/mtd/nand/raw/gpminand/gpmi-lib.c", função "gpmi_nfc_apply_timings". Basta comentar a chamada para "clk_set_rate". Pelo menos para mim isso funciona. Mais tarde percebi que seria melhor evitar a chamada apenas quando o processador for i.MX28, para permitir que funcione em chips posteriores.

Não analisei o que clk_set_rate exatamente faz e como ele deve ser invocado para funcionar em todos os processadores. Eu não tenho outro hardware, então não seria capaz de verificar isso.

informação relacionada