i.MX35 приостановить процессор и DDR2 от IRAM

Мне нужно перевести мое устройство в режим очень низкого энергопотребления из Linux 2.6.38, и поэтому необходимо приостановить все компоненты, включая CPU и DDR2.

До сих пор я обнаружил, что мне нужно скопировать функцию ассемблера ядра во внутреннюю память процессора и выполнить ее оттуда. В основном это выглядит так:

cpaddr = iram_alloc(SZ_1K, &iram_addr);
if(!cpaddr) return -ENOMEM;
suspend_iram_base = __arm_ioremap(iram_addr, SZ_1K, MT_HIGH_VECTORS);
memcpy(suspend_iram_base, cpu_v6_sdram_off, SZ_1K);
flush_icache_range(suspend_iram_base, suspend_iram_base + SZ_1K);
flush_cache_all();

__asm__ __volatile__(
  "ldr r0, %0\n"
  "ldr r1, %1\n"
  "ldr r2, %2\n"
  "blx r2\n"
  "nop\n"
  : : "m" (esdctl_addr),
      "m" (csd0_addr),
      "m" (suspend_iram_base));

Пока все работает как положено, я могу проверить выполнение кода из внутренней памяти (в виртуальном адресном пространстве) с помощью отладчика JTAG.

Если я все правильно понимаю, я должен сделать следующее в функции IRAM:

отключить прерывания и кэшиустановите контроллер SDRAM в режим отключения при предварительной зарядкевыполнить команду precharge all и получить доступ к памяти с максимумом A10 (например, 0x400), чтобы эффективно закрыть все банкиперевести процессор в режим ожидания, выполнив инструкцию WFIзатем снова включите все (оставлено в исходном коде ниже)

Соответствующий код выглядит так:

ENTRY(cpu_v6_sdram_off)
  @ r0: esdctl base address
  @ r1: csd0 address with a10 high

  cpsid   if

  @ disable I and D cache
  mrc     p15, 0, r2, c1, c0, 0
  bic     r2, r2, #0x00001000  @ disable I cache
  bic     r2, r2, #0x00000004  @ disable D cache
  mcr     p15, 0, r2, c1, c0, 0

  @ invalidate I cache
  mov     r2, #0
  mcr     p15, 0, r2, c7, c5, 0

  @ clear and invalidate D cache
  mov     r2, #0
  mcr     p15, 0, r2, c7, c14, 0

  @ precharge power down mode
  ldr     r2, [r0]
  bic     r2, r2, #0xc00
  orr     r2, r2, #0x400
  str     r2, [r0]

  @ precharge all command
  mov     r2, #0x92
  lsl     r2, #24
  orr     r2, r2, #0x228000
  orr     r2, r2, #0x0400
  str     r2, [r0]
  mov     r2, #0x12
  lsl     r2, #24
  orr     r2, r2, #0x340000
  orr     r2, r2, #0x5600
  orr     r2, r2, #0x78
  str     r2, [r1] @ dummy write access

  @ execute wait for interrupt
  mov     r1, #0
  mcr     p15, 0, r1, c7, c10, 4
  mcr     p15, 0, r1, c7, c0, 4

  cpsie   if
  bx      lr
ENDPROC(cpu_v6_sdram_off)

Проблема в том, что доступ к ОЗУ осуществляется с помощью фиктивной записи. Это просто приводит к исключению сбоя данных, а затем ЦП теряется. Если я пропущу эту часть, DDR2, похоже, не будет переведен в режим низкого энергопотребления, потому что потребление тока не снижается.

Теперь я полностью застрял и потерял идею здесь. Может кто-нибудь дать мне подсказку, что я делаю неправильно или чего мне здесь не хватает? Или есть какая-либо документация или исходный код, демонстрирующий всю процедуру для i.MX35 в Linux?

Ответы на вопрос(2)

Ваш ответ на вопрос