diff options
Diffstat (limited to 'arch/arm/mach-hisi/hisilicon.c')
-rw-r--r-- | arch/arm/mach-hisi/hisilicon.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/arm/mach-hisi/hisilicon.c b/arch/arm/mach-hisi/hisilicon.c index a9f648f3b80d..a7d555639bf6 100644 --- a/arch/arm/mach-hisi/hisilicon.c +++ b/arch/arm/mach-hisi/hisilicon.c @@ -11,12 +11,14 @@ * published by the Free Software Foundation. */ +#include <linux/ahci_platform.h> #include <linux/clk-provider.h> #include <linux/clocksource.h> #include <linux/irqchip.h> #include <linux/of_address.h> #include <linux/of_platform.h> +#include <asm/dma-iommu.h> #include <asm/proc-fns.h> #include <asm/mach/arch.h> @@ -94,6 +96,55 @@ static const char *hip04_compat[] __initconst = { NULL, }; +#ifdef CONFIG_ARM_SMMU +#define HIP04_AHCI_IOVA_START 0x20000000 +#define HIP04_AHCI_IOVA_SIZE 0x8000000 + +static int hip04_ahci_init(struct device *dev, void __iomem *addr) +{ + struct dma_iommu_mapping *mapping; + int ret; + + mapping = arm_iommu_create_mapping(&platform_bus_type, + HIP04_AHCI_IOVA_START, + HIP04_AHCI_IOVA_SIZE); + if (IS_ERR(mapping)) + return PTR_ERR(mapping); + + ret = arm_iommu_attach_device(dev, mapping); + return ret; +} + +static void hip04_ahci_exit(struct device *dev) +{ + struct dma_iommu_mapping *mapping; + + mapping = to_dma_iommu_mapping(dev); + arm_iommu_detach_device(dev); + arm_iommu_release_mapping(mapping); +} + +static struct ahci_platform_data hip04_ahci_pdata = { + .init = hip04_ahci_init, + .exit = hip04_ahci_exit, +}; + +static const struct of_dev_auxdata hip04_auxdata_lookup[] = { + OF_DEV_AUXDATA("hisilicon,hisi-ahci", 0xea000000, "ahci", + &hip04_ahci_pdata), + {} +}; + +static void __init hip04_init_machine(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, + hip04_auxdata_lookup, NULL); +} +#endif + DT_MACHINE_START(HIP04, "Hisilicon HiP04 (Flattened Device Tree)") .dt_compat = hip04_compat, +#ifdef CONFIG_ARM_SMMU + .init_machine = hip04_init_machine, +#endif MACHINE_END |