Differences

This shows you the differences between two versions of the page.

ru:toh:tp-link:tl-mr3420:deep.mmc.hack [2014/08/06 11:30] (current)
dioptimizer
Line 1: Line 1:
 +====== Расширенный моддинг MMC ======
 +
 +===== Способ подключения =====
 +{{http://www.mal4x.ru/download/file.php?id=409&mode=view&1g1.png?nolink|Способ подключения}}
 +
 +//Схема подключения успешно опробована на шине питания GPIO = 2.6V//
 +
 +Существует два способа модификации с использованием разных GPIO для CS1, а также два варианта установки необходимого ПО для непосредственного использования карточки памяти подключенной к устройству.\\
 +**Примечание:** Эта модификация, как и модификация [[:doc:howto:mmc_over_gpio|mmc_over_gpio]] - не поддерживает [[wp>ru:Secure_Digital#SDHC|SDHC]] карточки памяти на уровне драйвера.\\
 +
 +===== Подключение MMC/SD карты памяти к шине spi0.1 =====
 +
 +==== Основные изменения в прошивке ====
 +
 +<HTML><p style="border:2px dashed red;">Первый способ.</p></HTML>
 +=== Вариант GPIO как CS1 ===
 +В качестве CS для MMC/SD карты памяти, предпочтительнее использовать любой свободный GPIO пин.
 +
 +== Использование GPIO 7 - как CS1 для общей шины: ==
 +<code diff>
 +Index: target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c
 +===================================================================
 +--- target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c (revision 34914)
 ++++ target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c (working copy)
 +@@ -50,7 +50,7 @@
 + void __init ath79_register_m25p80(struct flash_platform_data *pdata)
 + {
 + ath79_spi_data.bus_num = 0;
 +- ath79_spi_data.num_chipselect = 1;
 ++ ath79_spi_data.num_chipselect = 2;
 + ath79_spi0_cdata.is_flash = true;
 + ath79_spi_info[0].platform_data = pdata;
 + ath79_register_spi(&ath79_spi_data, ath79_spi_info, 1);
 +Index: target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c
 +===================================================================
 +--- target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c (revision 34914)
 ++++ target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c (working copy)
 +@@ -9,6 +9,9 @@
 +  */
 +
 + #include <linux/gpio.h>
 ++#include <linux/mmc/host.h>
 ++#include <linux/spi/spi.h>
 ++#include <linux/spi/mmc_spi.h>
 +
 + #include <asm/mach-ath79/ath79.h>
 +
 +@@ -16,12 +19,14 @@
 + #include "dev-ap9x-pci.h"
 + #include "dev-gpio-buttons.h"
 + #include "dev-leds-gpio.h"
 ++#include "dev-spi.h"
 + #include "dev-m25p80.h"
 + #include "dev-usb.h"
 + #include "machtypes.h"
 +
 + #define TL_MR3X20_GPIO_LED_QSS 0
 + #define TL_MR3X20_GPIO_LED_SYSTEM 1
 ++#define TL_MR3X20_GPIO_CS1_MMC 7
 + #define TL_MR3X20_GPIO_LED_3G 8
 +
 + #define TL_MR3X20_GPIO_BTN_RESET 11
 +@@ -32,6 +37,26 @@
 + #define TL_MR3X20_KEYS_POLL_INTERVAL 20 /* msecs */
 + #define TL_MR3X20_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3X20_KEYS_POLL_INTERVAL)
 +
 ++static struct mmc_spi_platform_data ath79_mmc_data = {
 ++      .get_ro = NULL,
 ++      .get_cd = NULL,
 ++      .detect_delay = 100, /* msecs */
 ++ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
 ++};
 ++
 ++static struct ath79_spi_controller_data ath79_spi1_cdata = {
 ++ .cs_type = ATH79_SPI_CS_TYPE_GPIO,
 ++ .cs_line = TL_MR3X20_GPIO_CS1_MMC,
 ++};
 ++
 ++static struct spi_board_info ath79_spi_info[] = {
 ++ {
 ++ .bus_num = 0,
 ++ .chip_select = 1,
 ++ .max_speed_hz = 25000000,
 ++ .modalias = "mmc_spi",
 ++ .platform_data = &ath79_mmc_data,
 ++ .controller_data = &ath79_spi1_cdata,
 ++ }
 ++};
 ++
 + static const char *tl_mr3x20_part_probes[] = {
 + "tp-link",
 + NULL,
 +@@ -97,6 +122,9 @@
 + ath79_register_eth(0);
 +
 + ap91_pci_init(ee, mac);
 ++
 ++ spi_register_board_info(ath79_spi_info,
 ++ ARRAY_SIZE(ath79_spi_info));
 + }
 +
 + static void __init tl_mr3x20_usb_setup(void)
 +</code>
 +
 +<HTML><p style="border:2px dashed red;">Второй способ.</p></HTML>
 +=== Вариант Int. CS1 ===
 +
 +^ Internal CS ^ AR724X ^ AR933X ^
 +| CS1 | QSS LED (GPIO0) | UART In (GPIO9) |
 +| CS2 | SYS LED (GPIO1) | UART Out (GPIO10) |
 +На устройствах AR724X: Для того, чтобы использовать внутренний CS1 - необходимо [[#переключение.gpio0.qss.led.в.cs1.на.ar724x|отключить QSS LED]].
 +
 +На устройствах AR933X: Для того, чтобы использовать внутренний CS1 - необходимо [[#отключение.uart.и.переключение.gpio.9.rx.в.cs1.на.ar933x|отключить UART]].
 +
 +<code diff>
 +Index: target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c
 +===================================================================
 +--- target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c (revision 34914)
 ++++ target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c (working copy)
 +@@ -50,7 +50,7 @@
 + void __init ath79_register_m25p80(struct flash_platform_data *pdata)
 + {
 + ath79_spi_data.bus_num = 0;
 +- ath79_spi_data.num_chipselect = 1;
 ++ ath79_spi_data.num_chipselect = 2;
 + ath79_spi0_cdata.is_flash = true;
 + ath79_spi_info[0].platform_data = pdata;
 + ath79_register_spi(&ath79_spi_data, ath79_spi_info, 1);
 +Index: target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c
 +===================================================================
 +--- target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c (revision 34914)
 ++++ target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c (working copy)
 +@@ -9,13 +9,19 @@
 +  */
 +
 + #include <linux/gpio.h>
 ++#include <linux/mmc/host.h>
 ++#include <linux/spi/spi.h>
 ++#include <linux/spi/mmc_spi.h>
 +
 + #include <asm/mach-ath79/ath79.h>
 ++#include <asm/mach-ath79/ar71xx_regs.h>
 +
 ++#include "common.h"
 + #include "dev-eth.h"
 + #include "dev-ap9x-pci.h"
 + #include "dev-gpio-buttons.h"
 + #include "dev-leds-gpio.h"
 ++#include "dev-spi.h"
 + #include "dev-m25p80.h"
 + #include "dev-usb.h"
 + #include "machtypes.h"
 +@@ -32,6 +38,26 @@
 + #define TL_MR3X20_KEYS_POLL_INTERVAL 20 /* msecs */
 + #define TL_MR3X20_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3X20_KEYS_POLL_INTERVAL)
 +
 ++static struct mmc_spi_platform_data ath79_mmc_data = {
 ++ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
 ++};
 ++
 ++static struct ath79_spi_controller_data ath79_spi1_cdata = {
 ++ .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
 ++ .cs_line = 1,
 ++};
 ++
 ++static struct spi_board_info ath79_spi_info[] = {
 ++ {
 ++ .bus_num = 0,
 ++ .chip_select = 1,
 ++ .max_speed_hz = 25000000,
 ++ .modalias = "mmc_spi",
 ++ .platform_data = &ath79_mmc_data,
 ++ .controller_data = &ath79_spi1_cdata,
 ++ }
 ++};
 ++
 + static const char *tl_mr3x20_part_probes[] = {
 + "tp-link",
 + NULL,
 +@@ -80,6 +106,9 @@
 + u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
 + u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
 +
 ++ /* Enabling internal CS1, disable GPIO 0 */
 ++ ath79_gpio_function_enable(AR724X_GPIO_FUNC_SPI_CS_EN1);
 ++
 + ath79_register_m25p80(&tl_mr3x20_flash_data);
 +
 + ath79_register_gpio_keys_polled(-1, TL_MR3X20_KEYS_POLL_INTERVAL,
 +@@ -97,6 +126,9 @@
 + ath79_register_eth(0);
 +
 + ap91_pci_init(ee, mac);
 ++
 ++ spi_register_board_info(ath79_spi_info,
 ++ ARRAY_SIZE(ath79_spi_info));
 + }
 +
 + static void __init tl_mr3x20_usb_setup(void)
 +</code>
 +
 +== Переключение GPIO0 (QSS LED) в CS1 на AR724X: ==
 +
 +<code c>
 + /* Enabling internal CS1, disable GPIO 0 */
 + ath79_gpio_function_enable(AR724X_GPIO_FUNC_SPI_CS_EN1);
 +</code>
 +//(Уже используется в верхнем примере.)//
 +
 +== Отключение UART и переключение GPIO 9(Rx) в CS1 на AR933X: ==
 +<code c>
 + /* Disable UART, enabling GPIO 9 and GPIO 10 */
 + ath79_gpio_function_disable(AR933X_GPIO_FUNC_UART_EN);
 + /* Enabling internal CS1, disable GPIO 9 */
 + ath79_gpio_function_enable(AR933X_GPIO_FUNC_SPI_CS_EN1);
 +</code>
 +\\
 +=== Модули ===
 +<HTML><p style="border:2px dashed red;">Первый вариант.</p></HTML>
 +{{:meta:icons:tango:48px-emblem-important.svg.png?nolink |Важно!}}Использование внешних модулей ''kmod-mmc'' и ''kmod-mmc-spi'' - пока не позволяет корректно смонтировать ''<color magenta>/overlay</color>'' или ''<color blue>/</color>'' разделы через [[doc:howto:extroot]], данная ошибка описана в [[https://dev.openwrt.org/ticket/7768]]. Это даже с учетом того, что использование этих модулей, позволяет полноценно использовать карточку памяти и монтировать ее в другие точки монтирования (кроме [[doc:howto:extroot]]).
 +
 +**Обновление:** Проблема сохранилась по состоянию ревизии прошивки **r37142**.\\
 +Для [[doc:howto:extroot]], используйте Второй вариант.\\
 +\\
 +<HTML><p style="border:2px dashed red;">Второй вариант.</p></HTML>
 +== На уровне ядра (kernel): ==
 +<code diff>
 +Index: target/linux/ar71xx/config-3.7
 +===================================================================
 +--- target/linux/ar71xx/config-3.7 (revision 35363)
 ++++ target/linux/ar71xx/config-3.7 (working copy)
 +@@ -240,6 +240,10 @@
 + # CONFIG_SPI_RB4XX is not set
 + # CONFIG_SPI_RB4XX_CPLD is not set
 + # CONFIG_SPI_VSC7385 is not set
 ++CONFIG_EXT4_FS=y
 ++CONFIG_MMC=y
 ++CONFIG_MMC_SPI=y
 ++CONFIG_MMC_BLOCK=y
 ++CONFIG_MMC_TIFM_SD=n
 + CONFIG_SWCONFIG=y
 + CONFIG_SWCONFIG_LEDS=y
 + CONFIG_SYS_HAS_CPU_MIPS32_R2=y
 +</code>
 +//Помимо MMC модулей, здесь дополнительно включена возможность использовать EXT4 файловую систему на уровне ядра.\\
 +Также следует учесть, что Linux-ядро регулярно обновляется, а этот конфигурационный файл в названии носит версию ядра.\\
 +В конечном счете, если ядро Trank'а обновилось, необходимо найти этот же конфиг. файл (но уже новый, например: ''config-3.8'') и изменить его в соответствии с представленными здесь изменениями.//
 +
 +Интеграция необходимых модулей в ядро, позволяет использовать обнаруженную карточку памяти на ровне с флеш-памятью.\\
 +При этом, можно использовать карточку памяти в качестве расширенной файловой системы - [[doc:howto:extroot]].\\
 +\\
 +
 +==== Измерения ====
 +
 +== Тест скоростей spi0.1: ==
 +Скорость чтения/записи утилитой **dd**:
 +<code>
 +root@OpenWrt:~# /usr/bin/dd count=14 bs=1M if=/dev/mmcblk0p1 of=/dev/null
 +14+0 records in
 +14+0 records out
 +14680064 bytes (15 MB) copied, 20.9663 s, 700 kB/s
 +root@OpenWrt:~# /usr/bin/dd count=14 bs=1M if=/dev/zero of=/dev/mmcblk0p1
 +14+0 records in
 +14+0 records out
 +14680064 bytes (15 MB) copied, 25.2994 s, 580 kB/s
 +root@OpenWrt:~#
 +</code>
 +
 +Результат утилиты **hdparm**:
 +<code>
 +root@OpenWrt:~# hdparm -Tt /dev/mmcblk0p1
 +
 +/dev/mmcblk0p1:
 + Timing cached reads:    2 MB in  2.96 seconds = 691.37 kB/sec
 + Timing buffered disk reads:  2 MB in  3.05 seconds = 670.43 kB/sec
 +root@OpenWrt:~#
 +</code>
 +
 +== Нагрузка на CPU во время чтения/записи: ==
 +<HTML>
 +<pre class="code">
 +root@OpenWrt:~# top
 +Mem: 28224K used, 1120K free, 0K shrd, 5784K buff, 5592K cached
 +CPU:  0% usr  <font color="red">99% sys</font>  0% nic  0% idle  0% io  0% irq  0% sirq
 +Load average: 1.21 0.88 0.60 2/60 28540
 +  PID  PPID USER    STAT  VSZ %VSZ %CPU COMMAND
 + 2230    2 root    RW      0  0%  55% [kworker/u:2]
 + 2180    2 root    SW      0  0%  36% [kworker/u:0]
 +  559    2 root    RW      0  0%  6% [mmcqd/0]
 +...
 +</pre>
 +</HTML>
 +
 +**Итог:** Скорость чтения/записи по шине SPI, прямо зависит от скорости CPU.
 +
 +== Тест одновременного использования spi0.0 и spi0.1: ==
 +Здесь стоит уточнить способ выполнения теста. \\
 +Посылается две параллельные команды чтение\запись с разделительным command оператором "''&''" (запуск команды в фоне). \\
 +
 +Результат следующий:  при одновременном чтении или записи spi0.0 и spi0.1 (процесс не имеет значения), предпочтение дается шине spi0.1, т.е. пока не закончится операция чтении/записи блока на шине spi0.1 - на шине spi0.0 не начнется запрашиваемая операция, выполнение происходит в приоритетном порядке и не является ошибкой.
 +
 +== Питание: ==
 +^ Режим ^ Значение ^
 +| Спящий режим (простой) | ~1mA |
 +| Чтение данных | ~18mA |
 +| Запись данных | ~23mA |
 +
 +==== Логи ====
 +
 +== Лог загрузки и инициализации карточки: ==
 +<HTML>
 +<pre class="code">
 +...
 +<b><font size=4>[    0.730000] ath79-spi ath79-spi: master is unqueued, this is deprecated</font></b>
 +[    0.740000] m25p80 spi0.0: found en25f32, expected m25p80
 +[    0.750000] m25p80 spi0.0: en25f32 (4096 Kbytes)
 +[    0.750000] 5 tp-link partitions found on MTD device spi0.0
 +[    0.760000] Creating 5 MTD partitions on "spi0.0":
 +[    0.760000] 0x000000000000-0x000000020000 : "u-boot"
 +[    0.770000] 0x000000020000-0x00000013de00 : "kernel"
 +[    0.770000] mtd: partition "kernel" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only
 +[    0.790000] 0x00000013de00-0x0000003f0000 : "rootfs"
 +[    0.790000] mtd: partition "rootfs" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only
 +[    0.810000] mtd: partition "rootfs" set to be root filesystem
 +[    0.810000] mtd: partition "rootfs_data" created automatically, ofs=370000, len=80000
 +[    0.820000] 0x000000370000-0x0000003f0000 : "rootfs_data"
 +[    0.830000] 0x0000003f0000-0x000000400000 : "art"
 +[    0.840000] 0x000000020000-0x0000003f0000 : "firmware"
 +[    0.860000] libphy: ag71xx_mdio: probed
 +[    0.860000] eth0: Atheros AG71xx at 0xba000000, irq 5, mode:GMII
 +[    1.420000] eth0: Found an AR7240/AR9330 built-in switch
 +[    2.450000] eth1: Atheros AG71xx at 0xb9000000, irq 4, mode:MII
 +[    3.000000] ag71xx ag71xx.0 eth1: connected to PHY at ag71xx-mdio.1:04 [uid=004dd041, driver=Generic PHY]
 +<b><font size=4>[    3.050000] mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff</font></b>
 +[    3.060000] TCP: cubic registered
 +[    3.060000] NET: Registered protocol family 17
 +[    3.070000] 8021q: 802.1Q VLAN Support v1.8
 +[    3.080000] VFS: Mounted root (squashfs filesystem) readonly on device 31:2.
 +[    3.090000] Freeing unused kernel memory: 268k freed
 +<b><font size=4>[    3.310000] mmc0: host does not support reading read-only switch. assuming write-enable.
 +[    3.320000] mmc0: new SD card on SPI
 +[    3.480000] mmcblk0: mmc0:0000 00000 1.90 GiB
 +[    3.490000]  mmcblk0: p1</font></b>
 +...
 +</pre>
 +</HTML>
 +
 +== Вид ошибки в случае НЕ обнаружения карточки памяти на уровне ядра: ==
 +<code>
 +...
 +[    6.070000] mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff
 +...
 +[    8.710000] mmc0: error -145 whilst initialising SD card
 +...
 +[  10.710000] mmc0: error -145 whilst initialising MMC card
 +...
 +</code>
 +
 +
 +== Обнаруженные разделы: ==
 +<HTML>
 +<pre class="code">
 +root@OpenWrt:~# ls /dev/mmc*
 +<font color="magenta">/dev/mmcblk0    /dev/mmcblk0p1</font>
 +root@OpenWrt:~#
 +</pre>
 +</HTML>
 +
 +== Debug информация: ==
 +<code>
 +root@OpenWrt:~# cat /sys/kernel/debug/mmc0/ios
 +clock:          25000000 Hz
 +vdd:            20 (3.2 ~ 3.3 V)
 +bus mode:      2 (push-pull)
 +chip select:    1 (active high)
 +power mode:    2 (on)
 +bus width:      0 (1 bits)
 +timing spec:    0 (legacy)
 +signal voltage: 1 (3.30 V)
 +root@OpenWrt:~#
 +</code>

Back to top

ru/toh/tp-link/tl-mr3420/deep.mmc.hack.txt · Last modified: 2014/08/06 11:30 by dioptimizer