mmc: dw_mmc-bluefield: Add driver extension

This commit adds extension to the dw_mmc driver for Mellanox BlueField
SoC. It updates the UHS_REG_EXT register to bring up the eMMC card on
this SoC.

Signed-off-by: Liming Sun <lsun@mellanox.com>
Reviewed-by: David Woods <dwoods@mellanox.com>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
Liming Sun 2018-05-08 14:46:48 -04:00 committed by Ulf Hansson
parent 6d796c68cd
commit 86958dcc5a
3 changed files with 91 additions and 0 deletions

View File

@ -686,6 +686,15 @@ config MMC_DW_PLTFM
If unsure, say Y.
config MMC_DW_BLUEFIELD
tristate "BlueField specific extensions for Synopsys DW Memory Card Interface"
depends on MMC_DW
select MMC_DW_PLTFM
help
This selects support for Mellanox BlueField SoC specific extensions to
the Synopsys DesignWare Memory Card Interface driver. Select this
option for platforms based on Mellanox BlueField SoC's.
config MMC_DW_EXYNOS
tristate "Exynos specific extensions for Synopsys DW Memory Card Interface"
depends on MMC_DW

View File

@ -49,6 +49,7 @@ thunderx-mmc-objs := cavium.o cavium-thunderx.o
obj-$(CONFIG_MMC_CAVIUM_THUNDERX) += thunderx-mmc.o
obj-$(CONFIG_MMC_DW) += dw_mmc.o
obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o
obj-$(CONFIG_MMC_DW_BLUEFIELD) += dw_mmc-bluefield.o
obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o
obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_mmc-hi3798cv200.o
obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o

View File

@ -0,0 +1,81 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Mellanox Technologies.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include "dw_mmc.h"
#include "dw_mmc-pltfm.h"
#define UHS_REG_EXT_SAMPLE_MASK GENMASK(22, 16)
#define UHS_REG_EXT_DRIVE_MASK GENMASK(29, 23)
#define BLUEFIELD_UHS_REG_EXT_SAMPLE 2
#define BLUEFIELD_UHS_REG_EXT_DRIVE 4
static void dw_mci_bluefield_set_ios(struct dw_mci *host, struct mmc_ios *ios)
{
u32 reg;
/* Update the Drive and Sample fields in register UHS_REG_EXT. */
reg = mci_readl(host, UHS_REG_EXT);
reg &= ~UHS_REG_EXT_SAMPLE_MASK;
reg |= FIELD_PREP(UHS_REG_EXT_SAMPLE_MASK,
BLUEFIELD_UHS_REG_EXT_SAMPLE);
reg &= ~UHS_REG_EXT_DRIVE_MASK;
reg |= FIELD_PREP(UHS_REG_EXT_DRIVE_MASK, BLUEFIELD_UHS_REG_EXT_DRIVE);
mci_writel(host, UHS_REG_EXT, reg);
}
static const struct dw_mci_drv_data bluefield_drv_data = {
.set_ios = dw_mci_bluefield_set_ios
};
static const struct of_device_id dw_mci_bluefield_match[] = {
{ .compatible = "mellanox,bluefield-dw-mshc",
.data = &bluefield_drv_data },
{},
};
MODULE_DEVICE_TABLE(of, dw_mci_bluefield_match);
static int dw_mci_bluefield_probe(struct platform_device *pdev)
{
const struct dw_mci_drv_data *drv_data = NULL;
const struct of_device_id *match;
if (pdev->dev.of_node) {
match = of_match_node(dw_mci_bluefield_match,
pdev->dev.of_node);
drv_data = match->data;
}
return dw_mci_pltfm_register(pdev, drv_data);
}
static struct platform_driver dw_mci_bluefield_pltfm_driver = {
.probe = dw_mci_bluefield_probe,
.remove = dw_mci_pltfm_remove,
.driver = {
.name = "dwmmc_bluefield",
.of_match_table = dw_mci_bluefield_match,
.pm = &dw_mci_pltfm_pmops,
},
};
module_platform_driver(dw_mci_bluefield_pltfm_driver);
MODULE_DESCRIPTION("BlueField DW Multimedia Card driver");
MODULE_AUTHOR("Mellanox Technologies");
MODULE_LICENSE("GPL v2");