^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* linux/drivers/mmc/host/sdhci-s3c.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2008 Openmoko Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2008 Simtec Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Ben Dooks <ben@simtec.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * http://armlinux.simtec.co.uk/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * SDHCI (HSMMC) support for Samsung SoC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/platform_data/mmc-sdhci-s3c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/mmc/host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "sdhci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MAX_BUS_CLK (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define S3C_SDHCI_CONTROL2 (0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define S3C_SDHCI_CONTROL3 (0x84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define S3C64XX_SDHCI_CONTROL4 (0x8C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK BIT(30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define S3C_SDHCI_CTRL2_CDINVRXD3 BIT(29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define S3C_SDHCI_CTRL2_SLCARDOUT BIT(28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define S3C_SDHCI_CTRL2_FLTCLKSEL_MASK (0xf << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define S3C_SDHCI_CTRL2_FLTCLKSEL_SHIFT (24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define S3C_SDHCI_CTRL2_FLTCLKSEL(_x) ((_x) << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define S3C_SDHCI_CTRL2_LVLDAT_MASK (0xff << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define S3C_SDHCI_CTRL2_LVLDAT_SHIFT (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define S3C_SDHCI_CTRL2_LVLDAT(_x) ((_x) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define S3C_SDHCI_CTRL2_ENFBCLKTX BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define S3C_SDHCI_CTRL2_ENFBCLKRX BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define S3C_SDHCI_CTRL2_SDCDSEL BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define S3C_SDHCI_CTRL2_SDSIGPC BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define S3C_SDHCI_CTRL2_ENBUSYCHKTXSTART BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define S3C_SDHCI_CTRL2_DFCNT_MASK (0x3 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define S3C_SDHCI_CTRL2_DFCNT_SHIFT (9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define S3C_SDHCI_CTRL2_DFCNT_NONE (0x0 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define S3C_SDHCI_CTRL2_DFCNT_4SDCLK (0x1 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define S3C_SDHCI_CTRL2_DFCNT_16SDCLK (0x2 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define S3C_SDHCI_CTRL2_DFCNT_64SDCLK (0x3 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define S3C_SDHCI_CTRL2_ENCLKOUTHOLD BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define S3C_SDHCI_CTRL2_RWAITMODE BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define S3C_SDHCI_CTRL2_DISBUFRD BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define S3C_SDHCI_CTRL2_SELBASECLK_MASK (0x3 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define S3C_SDHCI_CTRL2_SELBASECLK_SHIFT (4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define S3C_SDHCI_CTRL2_PWRSYNC BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define S3C_SDHCI_CTRL2_ENCLKOUTMSKCON BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define S3C_SDHCI_CTRL2_HWINITFIN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define S3C_SDHCI_CTRL3_FCSEL3 BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define S3C_SDHCI_CTRL3_FCSEL2 BIT(23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define S3C_SDHCI_CTRL3_FCSEL1 BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define S3C_SDHCI_CTRL3_FCSEL0 BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define S3C_SDHCI_CTRL3_FIA3_MASK (0x7f << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define S3C_SDHCI_CTRL3_FIA3_SHIFT (24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define S3C_SDHCI_CTRL3_FIA3(_x) ((_x) << 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define S3C_SDHCI_CTRL3_FIA2_MASK (0x7f << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define S3C_SDHCI_CTRL3_FIA2_SHIFT (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define S3C_SDHCI_CTRL3_FIA2(_x) ((_x) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define S3C_SDHCI_CTRL3_FIA1_MASK (0x7f << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define S3C_SDHCI_CTRL3_FIA1_SHIFT (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define S3C_SDHCI_CTRL3_FIA1(_x) ((_x) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define S3C_SDHCI_CTRL3_FIA0_MASK (0x7f << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define S3C_SDHCI_CTRL3_FIA0_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define S3C_SDHCI_CTRL3_FIA0(_x) ((_x) << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define S3C64XX_SDHCI_CONTROL4_DRIVE_MASK (0x3 << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define S3C64XX_SDHCI_CONTROL4_DRIVE_SHIFT (16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define S3C64XX_SDHCI_CONTROL4_DRIVE_2mA (0x0 << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define S3C64XX_SDHCI_CONTROL4_DRIVE_4mA (0x1 << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define S3C64XX_SDHCI_CONTROL4_DRIVE_7mA (0x2 << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA (0x3 << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define S3C64XX_SDHCI_CONTROL4_BUSY (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * struct sdhci_s3c - S3C SDHCI instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @host: The SDHCI host created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @pdev: The platform device we where created from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @ioarea: The resource created when we claimed the IO area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * @pdata: The platform data for this controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @cur_clk: The index of the current bus clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * @ext_cd_irq: External card detect interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @clk_io: The clock for the internal bus interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @clk_rates: Clock frequencies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @clk_bus: The clocks that are available for the SD/MMC bus clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @no_divider: No or non-standard internal clock divider.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct sdhci_s3c {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct sdhci_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct resource *ioarea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct s3c_sdhci_platdata *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int cur_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int ext_cd_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct clk *clk_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct clk *clk_bus[MAX_BUS_CLK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned long clk_rates[MAX_BUS_CLK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) bool no_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * struct sdhci_s3c_driver_data - S3C SDHCI platform specific driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @sdhci_quirks: sdhci host specific quirks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @no_divider: no or non-standard internal clock divider.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * Specifies platform specific configuration of sdhci controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Note: A structure for driver specific platform data is used for future
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * expansion of its usage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct sdhci_s3c_drv_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) unsigned int sdhci_quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) bool no_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * sdhci_s3c_get_max_clk - callback to get maximum clock frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * @host: The SDHCI host instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * Callback to return the maximum clock rate acheivable by the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct sdhci_s3c *ourhost = to_s3c(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned long rate, max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) for (src = 0; src < MAX_BUS_CLK; src++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) rate = ourhost->clk_rates[src];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (rate > max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) max = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * sdhci_s3c_consider_clock - consider one the bus clocks for current setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * @ourhost: Our SDHCI instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * @src: The source clock index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * @wanted: The clock frequency wanted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned int src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) unsigned int wanted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct clk *clksrc = ourhost->clk_bus[src];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (IS_ERR(clksrc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return UINT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * If controller uses a non-standard clock division, find the best clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * speed possible with selected clock source and skip the division.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (ourhost->no_divider) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) rate = clk_round_rate(clksrc, wanted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return wanted - rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) rate = ourhost->clk_rates[src];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) for (shift = 0; shift <= 8; ++shift) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if ((rate >> shift) <= wanted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (shift > 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) dev_dbg(&ourhost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) "clk %d: rate %ld, min rate %lu > wanted %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) src, rate, rate / 256, wanted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return UINT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) src, rate, wanted, rate >> shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return wanted - (rate >> shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * sdhci_s3c_set_clock - callback on clock change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * @host: The SDHCI host being changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * @clock: The clock rate being requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * When the card's clock is going to be changed, look at the new frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * and find the best clock source to go with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct sdhci_s3c *ourhost = to_s3c(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) unsigned int best = UINT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) unsigned int delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) int best_src = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) u32 ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) host->mmc->actual_clock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* don't bother if the clock is going off. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (clock == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) sdhci_set_clock(host, clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) for (src = 0; src < MAX_BUS_CLK; src++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) delta = sdhci_s3c_consider_clock(ourhost, src, clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (delta < best) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) best = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) best_src = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) dev_dbg(&ourhost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) "selected source %d, clock %d, delta %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) best_src, clock, best);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* select the new clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (ourhost->cur_clk != best_src) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct clk *clk = ourhost->clk_bus[best_src];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (ourhost->cur_clk >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) clk_disable_unprepare(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ourhost->clk_bus[ourhost->cur_clk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ourhost->cur_clk = best_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) host->max_clk = ourhost->clk_rates[best_src];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* turn clock off to card before changing clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* reprogram default hardware configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) host->ioaddr + S3C64XX_SDHCI_CONTROL4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ctrl |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) S3C_SDHCI_CTRL2_ENFBCLKRX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) S3C_SDHCI_CTRL2_DFCNT_NONE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* reconfigure the controller for new clock rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ctrl = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (clock < 25 * 1000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) sdhci_set_clock(host, clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^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) * sdhci_s3c_get_min_clock - callback to get minimal supported clock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * @host: The SDHCI host being queried
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * To init mmc host properly a minimal clock value is needed. For high system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * bus clock's values the standard formula gives values out of allowed range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * The clock still can be set to lower values, if clock source other then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * system bus is selected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct sdhci_s3c *ourhost = to_s3c(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) unsigned long rate, min = ULONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) for (src = 0; src < MAX_BUS_CLK; src++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) rate = ourhost->clk_rates[src] / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (rate < min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) min = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* sdhci_cmu_get_max_clk - callback to get maximum clock frequency.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct sdhci_s3c *ourhost = to_s3c(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) unsigned long rate, max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) for (src = 0; src < MAX_BUS_CLK; src++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) clk = ourhost->clk_bus[src];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) rate = clk_round_rate(clk, ULONG_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (rate > max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) max = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct sdhci_s3c *ourhost = to_s3c(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) unsigned long rate, min = ULONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) for (src = 0; src < MAX_BUS_CLK; src++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) clk = ourhost->clk_bus[src];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) rate = clk_round_rate(clk, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (rate < min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) min = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* sdhci_cmu_set_clock - callback on clock change.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct sdhci_s3c *ourhost = to_s3c(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct device *dev = &ourhost->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) u16 clk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) host->mmc->actual_clock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* If the clock is going off, set to 0 at clock control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (clock == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) sdhci_s3c_set_clock(host, clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* Reset SD Clock Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) clk &= ~SDHCI_CLOCK_CARD_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret = clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dev_err(dev, "%s: failed to set clock rate %uHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mmc_hostname(host->mmc), clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) clk = SDHCI_CLOCK_INT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* Wait max 20 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) timeout = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) & SDHCI_CLOCK_INT_STABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) dev_err(dev, "%s: Internal clock never stabilised.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) mmc_hostname(host->mmc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) clk |= SDHCI_CLOCK_CARD_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static struct sdhci_ops sdhci_s3c_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .get_max_clock = sdhci_s3c_get_max_clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .set_clock = sdhci_s3c_set_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .get_min_clock = sdhci_s3c_get_min_clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .set_bus_width = sdhci_set_bus_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .reset = sdhci_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .set_uhs_signaling = sdhci_set_uhs_signaling,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static int sdhci_s3c_parse_dt(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) u32 max_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* if the bus-width property is not specified, assume width as 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (of_property_read_u32(node, "bus-width", &max_width))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) max_width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) pdata->max_width = max_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* get the card detection method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (of_get_property(node, "broken-cd", NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) pdata->cd_type = S3C_SDHCI_CD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (of_get_property(node, "non-removable", NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) pdata->cd_type = S3C_SDHCI_CD_PERMANENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (of_get_named_gpio(node, "cd-gpios", 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* assuming internal card detect that will be configured by pinctrl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) pdata->cd_type = S3C_SDHCI_CD_INTERNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int sdhci_s3c_parse_dt(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static const struct of_device_id sdhci_s3c_dt_match[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (pdev->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) match = of_match_node(sdhci_s3c_dt_match, pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return (struct sdhci_s3c_drv_data *)match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return (struct sdhci_s3c_drv_data *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) platform_get_device_id(pdev)->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int sdhci_s3c_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct s3c_sdhci_platdata *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct sdhci_s3c_drv_data *drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct sdhci_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct sdhci_s3c *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) int ret, irq, ptr, clks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!pdev->dev.platform_data && !pdev->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) dev_err(dev, "no device data specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (IS_ERR(host)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) dev_err(dev, "sdhci_alloc_host() failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return PTR_ERR(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) sc = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (!pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) goto err_pdata_io_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (pdev->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) goto err_pdata_io_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) drv_data = sdhci_s3c_get_driver_data(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) sc->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) sc->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) sc->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) sc->cur_clk = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) platform_set_drvdata(pdev, host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) sc->clk_io = devm_clk_get(dev, "hsmmc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (IS_ERR(sc->clk_io)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) dev_err(dev, "failed to get io clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ret = PTR_ERR(sc->clk_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) goto err_pdata_io_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* enable the local io clock and keep it running for the moment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) clk_prepare_enable(sc->clk_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) char name[14];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) snprintf(name, 14, "mmc_busclk.%d", ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) sc->clk_bus[ptr] = devm_clk_get(dev, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (IS_ERR(sc->clk_bus[ptr]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) clks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) sc->clk_rates[ptr] = clk_get_rate(sc->clk_bus[ptr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) dev_info(dev, "clock source %d: %s (%ld Hz)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ptr, name, sc->clk_rates[ptr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (clks == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) dev_err(dev, "failed to find any bus clocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) goto err_no_busclks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) host->ioaddr = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (IS_ERR(host->ioaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ret = PTR_ERR(host->ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) goto err_req_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* Ensure we have minimal gpio selected CMD/CLK/Detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (pdata->cfg_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) pdata->cfg_gpio(pdev, pdata->max_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) host->hw_name = "samsung-hsmmc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) host->ops = &sdhci_s3c_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) host->quirks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) host->quirks2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) host->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* Setup quirks for the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (drv_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) host->quirks |= drv_data->sdhci_quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) sc->no_divider = drv_data->no_divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) #ifndef CONFIG_MMC_SDHCI_S3C_DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /* we currently see overruns on errors, so disable the SDMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * support as well. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #endif /* CONFIG_MMC_SDHCI_S3C_DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* It seems we do not get an DATA transfer complete on non-busy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * transfers, not sure if this is a problem with this specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * SDHCI block, or a missing configuration that needs to be set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) host->quirks |= SDHCI_QUIRK_NO_BUSY_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /* This host supports the Auto CMD12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* Samsung SoCs need BROKEN_ADMA_ZEROLEN_DESC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) host->quirks |= SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (pdata->cd_type == S3C_SDHCI_CD_NONE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) host->mmc->caps = MMC_CAP_NONREMOVABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) switch (pdata->max_width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) host->mmc->caps |= MMC_CAP_8_BIT_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) host->mmc->caps |= MMC_CAP_4_BIT_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (pdata->pm_caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) host->mmc->pm_caps |= pdata->pm_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) SDHCI_QUIRK_32BIT_DMA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* HSMMC on Samsung SoCs uses SDCLK as timeout clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * If controller does not have internal clock divider,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * we can use overriding functions instead of default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (sc->no_divider) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /* It supports additional host capabilities if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (pdata->host_caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) host->mmc->caps |= pdata->host_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (pdata->host_caps2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) host->mmc->caps2 |= pdata->host_caps2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) pm_runtime_use_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) pm_suspend_ignore_children(&pdev->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) ret = mmc_of_parse(host->mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) goto err_req_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ret = sdhci_add_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) goto err_req_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) clk_disable_unprepare(sc->clk_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) err_req_regs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) err_no_busclks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) clk_disable_unprepare(sc->clk_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) err_pdata_io_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) sdhci_free_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static int sdhci_s3c_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct sdhci_host *host = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct sdhci_s3c *sc = sdhci_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (sc->ext_cd_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) free_irq(sc->ext_cd_irq, sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (sc->pdata->cd_type != S3C_SDHCI_CD_INTERNAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) clk_prepare_enable(sc->clk_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) sdhci_remove_host(host, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) pm_runtime_dont_use_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) clk_disable_unprepare(sc->clk_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) sdhci_free_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static int sdhci_s3c_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct sdhci_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (host->tuning_mode != SDHCI_TUNING_MODE_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) mmc_retune_needed(host->mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return sdhci_suspend_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static int sdhci_s3c_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct sdhci_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return sdhci_resume_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static int sdhci_s3c_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct sdhci_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct sdhci_s3c *ourhost = to_s3c(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct clk *busclk = ourhost->clk_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) ret = sdhci_runtime_suspend_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (host->tuning_mode != SDHCI_TUNING_MODE_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) mmc_retune_needed(host->mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (ourhost->cur_clk >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) clk_disable_unprepare(busclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static int sdhci_s3c_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct sdhci_host *host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct sdhci_s3c *ourhost = to_s3c(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct clk *busclk = ourhost->clk_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) clk_prepare_enable(busclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (ourhost->cur_clk >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) ret = sdhci_runtime_resume_host(host, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static const struct dev_pm_ops sdhci_s3c_pmops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) SET_SYSTEM_SLEEP_PM_OPS(sdhci_s3c_suspend, sdhci_s3c_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) SET_RUNTIME_PM_OPS(sdhci_s3c_runtime_suspend, sdhci_s3c_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static const struct platform_device_id sdhci_s3c_driver_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .name = "s3c-sdhci",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) .driver_data = (kernel_ulong_t)NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .no_divider = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) static const struct of_device_id sdhci_s3c_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) { .compatible = "samsung,s3c6410-sdhci", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) { .compatible = "samsung,exynos4210-sdhci",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .data = &exynos4_sdhci_drv_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) static struct platform_driver sdhci_s3c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) .probe = sdhci_s3c_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) .remove = sdhci_s3c_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) .id_table = sdhci_s3c_driver_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) .name = "s3c-sdhci",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) .probe_type = PROBE_PREFER_ASYNCHRONOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) .of_match_table = of_match_ptr(sdhci_s3c_dt_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) .pm = &sdhci_s3c_pmops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) module_platform_driver(sdhci_s3c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) MODULE_ALIAS("platform:s3c-sdhci");