Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (C) 2013 Broadcom Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * modify it under the terms of the GNU General Public License as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * published by the Free Software Foundation version 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * kind, whether express or implied; without even the implied warranty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/mmc/host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/mmc/slot-gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include "sdhci-pltfm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include "sdhci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define SDHCI_SOFT_RESET			0x01000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define KONA_SDHOST_CORECTRL			0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define KONA_SDHOST_CD_PINCTRL			0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define KONA_SDHOST_STOP_HCLK			0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define KONA_SDHOST_RESET			0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define KONA_SDHOST_EN				0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define KONA_SDHOST_CORESTAT			0x8004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define KONA_SDHOST_WP				0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define KONA_SDHOST_CD_SW			0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define KONA_SDHOST_COREIMR			0x8008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define KONA_SDHOST_IP				0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define KONA_SDHOST_COREISR			0x800C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define KONA_SDHOST_COREIMSR			0x8010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define KONA_SDHOST_COREDBG1			0x8014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define KONA_SDHOST_COREGPO_MASK		0x8018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define SD_DETECT_GPIO_DEBOUNCE_128MS		128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define KONA_MMC_AUTOSUSPEND_DELAY		(50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) struct sdhci_bcm_kona_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct mutex	write_lock; /* protect back to back writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) static int sdhci_bcm_kona_sd_reset(struct sdhci_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	/* This timeout should be sufficent for core to reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	timeout = jiffies + msecs_to_jiffies(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	/* reset the host using the top level reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	val |= KONA_SDHOST_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	while (!(sdhci_readl(host, KONA_SDHOST_CORECTRL) & KONA_SDHOST_RESET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		if (time_is_before_jiffies(timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			pr_err("Error: sd host is stuck in reset!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	/* bring the host out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	val &= ~KONA_SDHOST_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 * Back-to-Back writes to same register needs delay when SD bus clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	 * is very low w.r.t AHB clock, mainly during boot-time and during card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	 * insert-removal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	usleep_range(1000, 5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) static void sdhci_bcm_kona_sd_init(struct sdhci_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	/* enable the interrupt from the IP core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	val = sdhci_readl(host, KONA_SDHOST_COREIMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	val |= KONA_SDHOST_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	sdhci_writel(host, val, KONA_SDHOST_COREIMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	/* Enable the AHB clock gating module to the host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	val = sdhci_readl(host, KONA_SDHOST_CORECTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	val |= KONA_SDHOST_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	 * Back-to-Back register write needs a delay of 1ms at bootup (min 10uS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	 * Back-to-Back writes to same register needs delay when SD bus clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	 * is very low w.r.t AHB clock, mainly during boot-time and during card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	 * insert-removal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	usleep_range(1000, 5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	sdhci_writel(host, val, KONA_SDHOST_CORECTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * Software emulation of the SD card insertion/removal. Set insert=1 for insert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * and insert=0 for removal. The card detection is done by GPIO. For Broadcom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  * IP to function properly the bit 0 of CORESTAT register needs to be set/reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * to generate the CD IRQ handled in sdhci.c which schedules card_tasklet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int sdhci_bcm_kona_sd_card_emulate(struct sdhci_host *host, int insert)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	struct sdhci_pltfm_host *pltfm_priv = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	struct sdhci_bcm_kona_dev *kona_dev = sdhci_pltfm_priv(pltfm_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 * Back-to-Back register write needs a delay of min 10uS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	 * Back-to-Back writes to same register needs delay when SD bus clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	 * is very low w.r.t AHB clock, mainly during boot-time and during card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	 * insert-removal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	 * We keep 20uS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	mutex_lock(&kona_dev->write_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	val = sdhci_readl(host, KONA_SDHOST_CORESTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	if (insert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		ret = mmc_gpio_get_ro(host->mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			val = (val & ~KONA_SDHOST_WP) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 				((ret) ? KONA_SDHOST_WP : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		val |= KONA_SDHOST_CD_SW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		val &= ~KONA_SDHOST_CD_SW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		sdhci_writel(host, val, KONA_SDHOST_CORESTAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	mutex_unlock(&kona_dev->write_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * SD card interrupt event callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static void sdhci_bcm_kona_card_event(struct sdhci_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	if (mmc_gpio_get_cd(host->mmc) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		dev_dbg(mmc_dev(host->mmc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			"card inserted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		sdhci_bcm_kona_sd_card_emulate(host, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		dev_dbg(mmc_dev(host->mmc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			"card removed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		sdhci_bcm_kona_sd_card_emulate(host, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static void sdhci_bcm_kona_init_74_clocks(struct sdhci_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 				u8 power_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	 *  JEDEC and SD spec specify supplying 74 continuous clocks to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	 * device after power up. With minimum bus (100KHz) that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	 * that translates to 740us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (power_mode != MMC_POWER_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		udelay(740);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static const struct sdhci_ops sdhci_bcm_kona_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	.set_clock = sdhci_set_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	.platform_send_init_74_clocks = sdhci_bcm_kona_init_74_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	.set_bus_width = sdhci_set_bus_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	.reset = sdhci_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	.set_uhs_signaling = sdhci_set_uhs_signaling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	.card_event = sdhci_bcm_kona_card_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static const struct sdhci_pltfm_data sdhci_pltfm_data_kona = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	.ops    = &sdhci_bcm_kona_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	.quirks = SDHCI_QUIRK_NO_CARD_NO_RESET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_32BIT_DMA_ADDR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static const struct of_device_id sdhci_bcm_kona_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	{ .compatible = "brcm,kona-sdhci"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	{ .compatible = "bcm,kona-sdhci"}, /* deprecated name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) MODULE_DEVICE_TABLE(of, sdhci_bcm_kona_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int sdhci_bcm_kona_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	struct sdhci_bcm_kona_dev *kona_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	struct sdhci_pltfm_host *pltfm_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	struct sdhci_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	host = sdhci_pltfm_init(pdev, &sdhci_pltfm_data_kona,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			sizeof(*kona_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	if (IS_ERR(host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		return PTR_ERR(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	dev_dbg(dev, "%s: inited. IOADDR=%p\n", __func__, host->ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	pltfm_priv = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	kona_dev = sdhci_pltfm_priv(pltfm_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	mutex_init(&kona_dev->write_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	ret = mmc_of_parse(host->mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		goto err_pltfm_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (!host->mmc->f_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		dev_err(&pdev->dev, "Missing max-freq for SDHCI cfg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		ret = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		goto err_pltfm_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	/* Get and enable the core clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	pltfm_priv->clk = devm_clk_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (IS_ERR(pltfm_priv->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		dev_err(dev, "Failed to get core clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		ret = PTR_ERR(pltfm_priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		goto err_pltfm_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	ret = clk_set_rate(pltfm_priv->clk, host->mmc->f_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		dev_err(dev, "Failed to set rate core clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		goto err_pltfm_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	ret = clk_prepare_enable(pltfm_priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		dev_err(dev, "Failed to enable core clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		goto err_pltfm_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	dev_dbg(dev, "non-removable=%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		mmc_card_is_removable(host->mmc) ? 'N' : 'Y');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	dev_dbg(dev, "cd_gpio %c, wp_gpio %c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		(mmc_gpio_get_cd(host->mmc) != -ENOSYS) ? 'Y' : 'N',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		(mmc_gpio_get_ro(host->mmc) != -ENOSYS) ? 'Y' : 'N');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (!mmc_card_is_removable(host->mmc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	dev_dbg(dev, "is_8bit=%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		(host->mmc->caps & MMC_CAP_8_BIT_DATA) ? 'Y' : 'N');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	ret = sdhci_bcm_kona_sd_reset(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		goto err_clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	sdhci_bcm_kona_sd_init(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	ret = sdhci_add_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		goto err_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	/* if device is eMMC, emulate card insert right here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (!mmc_card_is_removable(host->mmc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		ret = sdhci_bcm_kona_sd_card_emulate(host, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 				"unable to emulate card insertion\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			goto err_remove_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	 * Since the card detection GPIO interrupt is configured to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	 * edge sensitive, check the initial GPIO value here, emulate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	 * only if the card is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	if (mmc_gpio_get_cd(host->mmc) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		sdhci_bcm_kona_sd_card_emulate(host, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	dev_dbg(dev, "initialized properly\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) err_remove_host:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	sdhci_remove_host(host, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) err_reset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	sdhci_bcm_kona_sd_reset(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) err_clk_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	clk_disable_unprepare(pltfm_priv->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) err_pltfm_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	sdhci_pltfm_free(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	dev_err(dev, "Probing of sdhci-pltfm failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static struct platform_driver sdhci_bcm_kona_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		.name	= "sdhci-kona",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		.pm	= &sdhci_pltfm_pmops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		.of_match_table = sdhci_bcm_kona_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	.probe		= sdhci_bcm_kona_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	.remove		= sdhci_pltfm_unregister,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) module_platform_driver(sdhci_bcm_kona_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) MODULE_DESCRIPTION("SDHCI driver for Broadcom Kona platform");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) MODULE_AUTHOR("Broadcom");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) MODULE_LICENSE("GPL v2");