Thread (5 messages) 5 messages, 4 authors, 2025-06-16

Re: [PATCH v1 5/9] mmc: sdhci: add Black Sesame Technologies BST C1200 controller driver

From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: 2025-05-28 09:06:55
Also in: linux-mmc, lkml

Hi Albert,

On Wed, 28 May 2025 at 10:55, Albert Yang [off-list ref] wrote:
Add a driver for the DesignWare Mobile Storage Host Controller (DWCMSHC)
SDHCI controller found in Black Sesame Technologies C1200 SoCs.

The driver provides specialized clock configuration, tuning, voltage
switching, and power management for the BST DWCMSHC controller. It also
includes support for eMMC boot and memory-mapped I/O for CRM registers.

Signed-off-by: Ge Gordon <gordon.ge@bst.ai>
Signed-off-by: Albert Yang <redacted>
Thanks for your patch!
quoted hunk ↗ jump to hunk
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -1112,3 +1112,14 @@ config MMC_LITEX
          module will be called litex_mmc.

          If unsure, say N.
+
+config MMC_SDHCI_BST
+       tristate "SDHCI OF support for the BST DWC MSHC"
depends on ARCH_BST || COMPILE_TEST
+       depends on MMC_SDHCI_PLTFM
+       depends on OF
+       depends on COMMON_CLK
+       help
+         This selects Synopsys DesignWare Cores Mobile Storage Controller
+         support.
+         If you have a controller with this interface, say Y or M here.
+         If unsure, say N.
quoted hunk ↗ jump to hunk
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of-bst-c1200.c
+#define SDEMMC_CRM_BCLK_DIV_CTRL       0x08
+#define SDEMMC_CRM_RX_CLK_CTRL         0x14
+#define SDEMMC_CRM_TIMER_DIV_CTRL      0x0C
+#define SDEMMC_CRM_VOL_CTRL            0x1C
+#define DRIVER_NAME                    "sdhci_bst"
+#define BST_VOL_STABLE_ON              (0x1 << 7)
+#define SDHCI_DUMP_BST(f, x...)                \
+       pr_info("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ##x)
+#define SD_3_3V                                0
+#define SD_1_8V                                1
+#define default_max_freq               200000ul
+
+void sdhci_bst_print_vendor(struct sdhci_host *host)
+{
+       SDHCI_DUMP_BST("============ SDHCI VENDOR REGISTER DUMP ===========\n");
+
+       SDHCI_DUMP_BST("VER_ID:  0x%08x | VER_TPYE:  0x%08x\n",
+                      sdhci_readl(host, SDHC_MHSC_VER_ID_R),
+                      sdhci_readl(host, SDHC_MHSC_VER_TPYE_R));
+       SDHCI_DUMP_BST("MHSC_CTRL:  0x%08x | MBIU_CTRL:  0x%08x\n",
+                      sdhci_readw(host, SDHC_MHSC_CTRL_R),
+                      sdhci_readw(host, SDHC_MBIU_CTRL_R));
+       SDHCI_DUMP_BST("EMMC_CTRL:  0x%08x | BOOT_CTRL: 0x%08x\n",
+                      sdhci_readl(host, SDHC_EMMC_CTRL_R),
+                      sdhci_readw(host, SDHC_BOOT_CTRL_R));
+       SDHCI_DUMP_BST("GP_IN:   0x%08x | GP_OUT: 0x%08x\n",
+                      sdhci_readl(host, SDHC_GP_IN_R),
+                      sdhci_readb(host, SDHC_GP_OUT_R));
+       SDHCI_DUMP_BST("AT_CTRL:     0x%08x | AT_STAT:  0x%08x\n",
+                      sdhci_readb(host, SDHC_AT_CTRL_R),
+                      sdhci_readb(host, SDHC_AT_STAT_R));
+}
+EXPORT_SYMBOL_GPL(sdhci_bst_print_vendor);
Why do you need this?
+
+static u32 bst_read_phys_bst(u32 phys_addr)
+{
+       u32 phys_addr_page = phys_addr & 0xFFFFE000;
+       u32 phys_offset = phys_addr & 0x00001FFF;
+       u32 map_size = phys_offset + sizeof(u32);
+       u32 ret = 0xDEADBEEF;
+       void *mem_mapped = ioremap(phys_addr_page, map_size);
+
+       if (mem_mapped) {
+               ret = (u32)ioread32(((u8 *)mem_mapped) + phys_offset);
+               iounmap(mem_mapped);
+       }
Please do not ioremap()/iounmap() for each register read...
+
+       return ret;
+}
+
+static void bst_write_phys_bst(u32 phys_addr, u32 value)
+{
+       u32 phys_addr_page = phys_addr & 0xFFFFE000;
+       u32 phys_offset = phys_addr & 0x00001FFF;
+       u32 map_size = phys_offset + sizeof(u32);
+       void *mem_mapped = ioremap(phys_addr_page, map_size);
+
+       if (mem_mapped) {
+               iowrite32(value, ((u8 *)mem_mapped) + phys_offset);
+               iounmap(mem_mapped);
+       }
or write...
+}
Aborting review.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help