mmc: sdhci-pci-gli: Add Genesys Logic GL9767 support
Add support for the GL9767 chipset. GL9767 supports SD3 mode likes UHS-I SDR50, SDR104. Enable MSI interrupt for GL9767. Some platform do not support PCI INTx and devices can not work without interrupt. Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw> Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Link: https://lore.kernel.org/r/20230609071441.451464-2-victorshihgli@gmail.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
parent
f2764e1f79
commit
f3a5b56c12
|
@ -1903,6 +1903,7 @@ static const struct pci_device_id pci_ids[] = {
|
|||
SDHCI_PCI_DEVICE(GLI, 9750, gl9750),
|
||||
SDHCI_PCI_DEVICE(GLI, 9755, gl9755),
|
||||
SDHCI_PCI_DEVICE(GLI, 9763E, gl9763e),
|
||||
SDHCI_PCI_DEVICE(GLI, 9767, gl9767),
|
||||
SDHCI_PCI_DEVICE_CLASS(AMD, SYSTEM_SDHCI, PCI_CLASS_MASK, amd),
|
||||
/* Generic SD host controller */
|
||||
{PCI_DEVICE_CLASS(SYSTEM_SDHCI, PCI_CLASS_MASK)},
|
||||
|
|
|
@ -149,6 +149,32 @@
|
|||
#define PCI_GLI_9755_PM_CTRL 0xFC
|
||||
#define PCI_GLI_9755_PM_STATE GENMASK(1, 0)
|
||||
|
||||
#define SDHCI_GLI_9767_GM_BURST_SIZE 0x510
|
||||
#define SDHCI_GLI_9767_GM_BURST_SIZE_AXI_ALWAYS_SET BIT(8)
|
||||
|
||||
#define PCIE_GLI_9767_VHS 0x884
|
||||
#define GLI_9767_VHS_REV GENMASK(19, 16)
|
||||
#define GLI_9767_VHS_REV_R 0x0
|
||||
#define GLI_9767_VHS_REV_M 0x1
|
||||
#define GLI_9767_VHS_REV_W 0x2
|
||||
|
||||
#define PCIE_GLI_9767_PWR_MACRO_CTL 0x8D0
|
||||
#define PCIE_GLI_9767_PWR_MACRO_CTL_LOW_VOLTAGE GENMASK(3, 0)
|
||||
#define PCIE_GLI_9767_PWR_MACRO_CTL_LD0_LOW_OUTPUT_VOLTAGE GENMASK(15, 12)
|
||||
#define PCIE_GLI_9767_PWR_MACRO_CTL_LD0_LOW_OUTPUT_VOLTAGE_VALUE 0x7
|
||||
#define PCIE_GLI_9767_PWR_MACRO_CTL_RCLK_AMPLITUDE_CTL GENMASK(29, 28)
|
||||
#define PCIE_GLI_9767_PWR_MACRO_CTL_RCLK_AMPLITUDE_CTL_VALUE 0x3
|
||||
|
||||
#define PCIE_GLI_9767_SCR 0x8E0
|
||||
#define PCIE_GLI_9767_SCR_AUTO_AXI_W_BURST BIT(6)
|
||||
#define PCIE_GLI_9767_SCR_AUTO_AXI_R_BURST BIT(7)
|
||||
#define PCIE_GLI_9767_SCR_AXI_REQ BIT(9)
|
||||
#define PCIE_GLI_9767_SCR_CARD_DET_PWR_SAVING_EN BIT(10)
|
||||
#define PCIE_GLI_9767_SCR_SYSTEM_CLK_SELECT_MODE0 BIT(16)
|
||||
#define PCIE_GLI_9767_SCR_SYSTEM_CLK_SELECT_MODE1 BIT(17)
|
||||
#define PCIE_GLI_9767_SCR_CORE_PWR_D3_OFF BIT(21)
|
||||
#define PCIE_GLI_9767_SCR_CFG_RST_DATA_LINK_DOWN BIT(30)
|
||||
|
||||
#define GLI_MAX_TUNING_LOOP 40
|
||||
|
||||
/* Genesys Logic chipset */
|
||||
|
@ -693,6 +719,89 @@ static void gl9755_hw_setting(struct sdhci_pci_slot *slot)
|
|||
gl9755_wt_off(pdev);
|
||||
}
|
||||
|
||||
static inline void gl9767_vhs_read(struct pci_dev *pdev)
|
||||
{
|
||||
u32 vhs_enable;
|
||||
u32 vhs_value;
|
||||
|
||||
pci_read_config_dword(pdev, PCIE_GLI_9767_VHS, &vhs_value);
|
||||
vhs_enable = FIELD_GET(GLI_9767_VHS_REV, vhs_value);
|
||||
|
||||
if (vhs_enable == GLI_9767_VHS_REV_R)
|
||||
return;
|
||||
|
||||
vhs_value &= ~GLI_9767_VHS_REV;
|
||||
vhs_value |= FIELD_PREP(GLI_9767_VHS_REV, GLI_9767_VHS_REV_R);
|
||||
|
||||
pci_write_config_dword(pdev, PCIE_GLI_9767_VHS, vhs_value);
|
||||
}
|
||||
|
||||
static inline void gl9767_vhs_write(struct pci_dev *pdev)
|
||||
{
|
||||
u32 vhs_enable;
|
||||
u32 vhs_value;
|
||||
|
||||
pci_read_config_dword(pdev, PCIE_GLI_9767_VHS, &vhs_value);
|
||||
vhs_enable = FIELD_GET(GLI_9767_VHS_REV, vhs_value);
|
||||
|
||||
if (vhs_enable == GLI_9767_VHS_REV_W)
|
||||
return;
|
||||
|
||||
vhs_value &= ~GLI_9767_VHS_REV;
|
||||
vhs_value |= FIELD_PREP(GLI_9767_VHS_REV, GLI_9767_VHS_REV_W);
|
||||
|
||||
pci_write_config_dword(pdev, PCIE_GLI_9767_VHS, vhs_value);
|
||||
}
|
||||
|
||||
static void gli_set_9767(struct sdhci_host *host)
|
||||
{
|
||||
u32 value;
|
||||
|
||||
value = sdhci_readl(host, SDHCI_GLI_9767_GM_BURST_SIZE);
|
||||
value &= ~SDHCI_GLI_9767_GM_BURST_SIZE_AXI_ALWAYS_SET;
|
||||
sdhci_writel(host, value, SDHCI_GLI_9767_GM_BURST_SIZE);
|
||||
}
|
||||
|
||||
static void gl9767_hw_setting(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
struct pci_dev *pdev = slot->chip->pdev;
|
||||
u32 value;
|
||||
|
||||
gl9767_vhs_write(pdev);
|
||||
|
||||
pci_read_config_dword(pdev, PCIE_GLI_9767_PWR_MACRO_CTL, &value);
|
||||
value &= ~(PCIE_GLI_9767_PWR_MACRO_CTL_LOW_VOLTAGE |
|
||||
PCIE_GLI_9767_PWR_MACRO_CTL_LD0_LOW_OUTPUT_VOLTAGE |
|
||||
PCIE_GLI_9767_PWR_MACRO_CTL_RCLK_AMPLITUDE_CTL);
|
||||
|
||||
value |= PCIE_GLI_9767_PWR_MACRO_CTL_LOW_VOLTAGE |
|
||||
FIELD_PREP(PCIE_GLI_9767_PWR_MACRO_CTL_LD0_LOW_OUTPUT_VOLTAGE,
|
||||
PCIE_GLI_9767_PWR_MACRO_CTL_LD0_LOW_OUTPUT_VOLTAGE_VALUE) |
|
||||
FIELD_PREP(PCIE_GLI_9767_PWR_MACRO_CTL_RCLK_AMPLITUDE_CTL,
|
||||
PCIE_GLI_9767_PWR_MACRO_CTL_RCLK_AMPLITUDE_CTL_VALUE);
|
||||
pci_write_config_dword(pdev, PCIE_GLI_9767_PWR_MACRO_CTL, value);
|
||||
|
||||
pci_read_config_dword(pdev, PCIE_GLI_9767_SCR, &value);
|
||||
value &= ~(PCIE_GLI_9767_SCR_SYSTEM_CLK_SELECT_MODE0 |
|
||||
PCIE_GLI_9767_SCR_SYSTEM_CLK_SELECT_MODE1 |
|
||||
PCIE_GLI_9767_SCR_CFG_RST_DATA_LINK_DOWN);
|
||||
|
||||
value |= PCIE_GLI_9767_SCR_AUTO_AXI_W_BURST |
|
||||
PCIE_GLI_9767_SCR_AUTO_AXI_R_BURST |
|
||||
PCIE_GLI_9767_SCR_AXI_REQ |
|
||||
PCIE_GLI_9767_SCR_CARD_DET_PWR_SAVING_EN |
|
||||
PCIE_GLI_9767_SCR_CORE_PWR_D3_OFF;
|
||||
pci_write_config_dword(pdev, PCIE_GLI_9767_SCR, value);
|
||||
|
||||
gl9767_vhs_read(pdev);
|
||||
}
|
||||
|
||||
static void sdhci_gl9767_reset(struct sdhci_host *host, u8 mask)
|
||||
{
|
||||
sdhci_reset(host, mask);
|
||||
gli_set_9767(host);
|
||||
}
|
||||
|
||||
static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
struct sdhci_host *host = slot->host;
|
||||
|
@ -717,6 +826,19 @@ static int gli_probe_slot_gl9755(struct sdhci_pci_slot *slot)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gli_probe_slot_gl9767(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
struct sdhci_host *host = slot->host;
|
||||
|
||||
gli_set_9767(host);
|
||||
gl9767_hw_setting(slot);
|
||||
gli_pcie_enable_msi(slot);
|
||||
slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO;
|
||||
sdhci_enable_v4_mode(host);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sdhci_gli_voltage_switch(struct sdhci_host *host)
|
||||
{
|
||||
/*
|
||||
|
@ -740,6 +862,25 @@ static void sdhci_gli_voltage_switch(struct sdhci_host *host)
|
|||
usleep_range(100000, 110000);
|
||||
}
|
||||
|
||||
static void sdhci_gl9767_voltage_switch(struct sdhci_host *host)
|
||||
{
|
||||
/*
|
||||
* According to Section 3.6.1 signal voltage switch procedure in
|
||||
* SD Host Controller Simplified Spec. 4.20, steps 6~8 are as
|
||||
* follows:
|
||||
* (6) Set 1.8V Signal Enable in the Host Control 2 register.
|
||||
* (7) Wait 5ms. 1.8V voltage regulator shall be stable within this
|
||||
* period.
|
||||
* (8) If 1.8V Signal Enable is cleared by Host Controller, go to
|
||||
* step (12).
|
||||
*
|
||||
* Wait 5ms after set 1.8V signal enable in Host Control 2 register
|
||||
* to ensure 1.8V signal enable bit is set by GL9767.
|
||||
*
|
||||
*/
|
||||
usleep_range(5000, 5500);
|
||||
}
|
||||
|
||||
static void sdhci_gl9750_reset(struct sdhci_host *host, u8 mask)
|
||||
{
|
||||
sdhci_reset(host, mask);
|
||||
|
@ -1150,3 +1291,22 @@ const struct sdhci_pci_fixes sdhci_gl9763e = {
|
|||
#endif
|
||||
.add_host = gl9763e_add_host,
|
||||
};
|
||||
|
||||
static const struct sdhci_ops sdhci_gl9767_ops = {
|
||||
.set_clock = sdhci_set_clock,
|
||||
.enable_dma = sdhci_pci_enable_dma,
|
||||
.set_bus_width = sdhci_set_bus_width,
|
||||
.reset = sdhci_gl9767_reset,
|
||||
.set_uhs_signaling = sdhci_set_uhs_signaling,
|
||||
.voltage_switch = sdhci_gl9767_voltage_switch,
|
||||
};
|
||||
|
||||
const struct sdhci_pci_fixes sdhci_gl9767 = {
|
||||
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
|
||||
.quirks2 = SDHCI_QUIRK2_BROKEN_DDR50,
|
||||
.probe_slot = gli_probe_slot_gl9767,
|
||||
.ops = &sdhci_gl9767_ops,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.resume = sdhci_pci_gli_resume,
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
#define PCI_DEVICE_ID_GLI_9755 0x9755
|
||||
#define PCI_DEVICE_ID_GLI_9750 0x9750
|
||||
#define PCI_DEVICE_ID_GLI_9763E 0xe763
|
||||
#define PCI_DEVICE_ID_GLI_9767 0x9767
|
||||
|
||||
/*
|
||||
* PCI device class and mask
|
||||
|
@ -195,5 +196,6 @@ extern const struct sdhci_pci_fixes sdhci_o2;
|
|||
extern const struct sdhci_pci_fixes sdhci_gl9750;
|
||||
extern const struct sdhci_pci_fixes sdhci_gl9755;
|
||||
extern const struct sdhci_pci_fixes sdhci_gl9763e;
|
||||
extern const struct sdhci_pci_fixes sdhci_gl9767;
|
||||
|
||||
#endif /* __SDHCI_PCI_H */
|
||||
|
|
Loading…
Reference in New Issue