11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 28428e5adSDave Gerlach /* 38428e5adSDave Gerlach * TI AM33XX SRAM EMIF Driver 48428e5adSDave Gerlach * 58428e5adSDave Gerlach * Copyright (C) 2016-2017 Texas Instruments Inc. 68428e5adSDave Gerlach * Dave Gerlach 78428e5adSDave Gerlach */ 88428e5adSDave Gerlach 98428e5adSDave Gerlach #include <linux/err.h> 108428e5adSDave Gerlach #include <linux/genalloc.h> 118428e5adSDave Gerlach #include <linux/io.h> 128428e5adSDave Gerlach #include <linux/kernel.h> 138428e5adSDave Gerlach #include <linux/module.h> 148428e5adSDave Gerlach #include <linux/of.h> 158428e5adSDave Gerlach #include <linux/of_platform.h> 168428e5adSDave Gerlach #include <linux/platform_device.h> 178428e5adSDave Gerlach #include <linux/sram.h> 188428e5adSDave Gerlach #include <linux/ti-emif-sram.h> 198428e5adSDave Gerlach 208428e5adSDave Gerlach #include "emif.h" 218428e5adSDave Gerlach 228428e5adSDave Gerlach #define TI_EMIF_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \ 238428e5adSDave Gerlach (unsigned long)&ti_emif_sram) 248428e5adSDave Gerlach 258428e5adSDave Gerlach #define EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES 0x00a0 268428e5adSDave Gerlach 278428e5adSDave Gerlach struct ti_emif_data { 288428e5adSDave Gerlach phys_addr_t ti_emif_sram_phys; 298428e5adSDave Gerlach phys_addr_t ti_emif_sram_data_phys; 308428e5adSDave Gerlach unsigned long ti_emif_sram_virt; 318428e5adSDave Gerlach unsigned long ti_emif_sram_data_virt; 328428e5adSDave Gerlach struct gen_pool *sram_pool_code; 338428e5adSDave Gerlach struct gen_pool *sram_pool_data; 348428e5adSDave Gerlach struct ti_emif_pm_data pm_data; 358428e5adSDave Gerlach struct ti_emif_pm_functions pm_functions; 368428e5adSDave Gerlach }; 378428e5adSDave Gerlach 388428e5adSDave Gerlach static struct ti_emif_data *emif_instance; 398428e5adSDave Gerlach 408428e5adSDave Gerlach static u32 sram_suspend_address(struct ti_emif_data *emif_data, 418428e5adSDave Gerlach unsigned long addr) 428428e5adSDave Gerlach { 438428e5adSDave Gerlach return (emif_data->ti_emif_sram_virt + 448428e5adSDave Gerlach TI_EMIF_SRAM_SYMBOL_OFFSET(addr)); 458428e5adSDave Gerlach } 468428e5adSDave Gerlach 478428e5adSDave Gerlach static phys_addr_t sram_resume_address(struct ti_emif_data *emif_data, 488428e5adSDave Gerlach unsigned long addr) 498428e5adSDave Gerlach { 508428e5adSDave Gerlach return ((unsigned long)emif_data->ti_emif_sram_phys + 518428e5adSDave Gerlach TI_EMIF_SRAM_SYMBOL_OFFSET(addr)); 528428e5adSDave Gerlach } 538428e5adSDave Gerlach 548428e5adSDave Gerlach static void ti_emif_free_sram(struct ti_emif_data *emif_data) 558428e5adSDave Gerlach { 568428e5adSDave Gerlach gen_pool_free(emif_data->sram_pool_code, emif_data->ti_emif_sram_virt, 578428e5adSDave Gerlach ti_emif_sram_sz); 588428e5adSDave Gerlach gen_pool_free(emif_data->sram_pool_data, 598428e5adSDave Gerlach emif_data->ti_emif_sram_data_virt, 608428e5adSDave Gerlach sizeof(struct emif_regs_amx3)); 618428e5adSDave Gerlach } 628428e5adSDave Gerlach 638428e5adSDave Gerlach static int ti_emif_alloc_sram(struct device *dev, 648428e5adSDave Gerlach struct ti_emif_data *emif_data) 658428e5adSDave Gerlach { 668428e5adSDave Gerlach struct device_node *np = dev->of_node; 678428e5adSDave Gerlach int ret; 688428e5adSDave Gerlach 698428e5adSDave Gerlach emif_data->sram_pool_code = of_gen_pool_get(np, "sram", 0); 708428e5adSDave Gerlach if (!emif_data->sram_pool_code) { 718428e5adSDave Gerlach dev_err(dev, "Unable to get sram pool for ocmcram code\n"); 728428e5adSDave Gerlach return -ENODEV; 738428e5adSDave Gerlach } 748428e5adSDave Gerlach 758428e5adSDave Gerlach emif_data->ti_emif_sram_virt = 768428e5adSDave Gerlach gen_pool_alloc(emif_data->sram_pool_code, 778428e5adSDave Gerlach ti_emif_sram_sz); 788428e5adSDave Gerlach if (!emif_data->ti_emif_sram_virt) { 798428e5adSDave Gerlach dev_err(dev, "Unable to allocate code memory from ocmcram\n"); 808428e5adSDave Gerlach return -ENOMEM; 818428e5adSDave Gerlach } 828428e5adSDave Gerlach 838428e5adSDave Gerlach /* Save physical address to calculate resume offset during pm init */ 848428e5adSDave Gerlach emif_data->ti_emif_sram_phys = 858428e5adSDave Gerlach gen_pool_virt_to_phys(emif_data->sram_pool_code, 868428e5adSDave Gerlach emif_data->ti_emif_sram_virt); 878428e5adSDave Gerlach 888428e5adSDave Gerlach /* Get sram pool for data section and allocate space */ 898428e5adSDave Gerlach emif_data->sram_pool_data = of_gen_pool_get(np, "sram", 1); 908428e5adSDave Gerlach if (!emif_data->sram_pool_data) { 918428e5adSDave Gerlach dev_err(dev, "Unable to get sram pool for ocmcram data\n"); 928428e5adSDave Gerlach ret = -ENODEV; 938428e5adSDave Gerlach goto err_free_sram_code; 948428e5adSDave Gerlach } 958428e5adSDave Gerlach 968428e5adSDave Gerlach emif_data->ti_emif_sram_data_virt = 978428e5adSDave Gerlach gen_pool_alloc(emif_data->sram_pool_data, 988428e5adSDave Gerlach sizeof(struct emif_regs_amx3)); 998428e5adSDave Gerlach if (!emif_data->ti_emif_sram_data_virt) { 1008428e5adSDave Gerlach dev_err(dev, "Unable to allocate data memory from ocmcram\n"); 1018428e5adSDave Gerlach ret = -ENOMEM; 1028428e5adSDave Gerlach goto err_free_sram_code; 1038428e5adSDave Gerlach } 1048428e5adSDave Gerlach 1058428e5adSDave Gerlach /* Save physical address to calculate resume offset during pm init */ 1068428e5adSDave Gerlach emif_data->ti_emif_sram_data_phys = 1078428e5adSDave Gerlach gen_pool_virt_to_phys(emif_data->sram_pool_data, 1088428e5adSDave Gerlach emif_data->ti_emif_sram_data_virt); 1098428e5adSDave Gerlach /* 1108428e5adSDave Gerlach * These functions are called during suspend path while MMU is 1118428e5adSDave Gerlach * still on so add virtual base to offset for absolute address 1128428e5adSDave Gerlach */ 1138428e5adSDave Gerlach emif_data->pm_functions.save_context = 1148428e5adSDave Gerlach sram_suspend_address(emif_data, 1158428e5adSDave Gerlach (unsigned long)ti_emif_save_context); 1168428e5adSDave Gerlach emif_data->pm_functions.enter_sr = 1178428e5adSDave Gerlach sram_suspend_address(emif_data, 1188428e5adSDave Gerlach (unsigned long)ti_emif_enter_sr); 1198428e5adSDave Gerlach emif_data->pm_functions.abort_sr = 1208428e5adSDave Gerlach sram_suspend_address(emif_data, 1218428e5adSDave Gerlach (unsigned long)ti_emif_abort_sr); 1228428e5adSDave Gerlach 1238428e5adSDave Gerlach /* 1248428e5adSDave Gerlach * These are called during resume path when MMU is not enabled 1258428e5adSDave Gerlach * so physical address is used instead 1268428e5adSDave Gerlach */ 1278428e5adSDave Gerlach emif_data->pm_functions.restore_context = 1288428e5adSDave Gerlach sram_resume_address(emif_data, 1298428e5adSDave Gerlach (unsigned long)ti_emif_restore_context); 1308428e5adSDave Gerlach emif_data->pm_functions.exit_sr = 1318428e5adSDave Gerlach sram_resume_address(emif_data, 1328428e5adSDave Gerlach (unsigned long)ti_emif_exit_sr); 1336c110561SDave Gerlach emif_data->pm_functions.run_hw_leveling = 1346c110561SDave Gerlach sram_resume_address(emif_data, 1356c110561SDave Gerlach (unsigned long)ti_emif_run_hw_leveling); 1368428e5adSDave Gerlach 1378428e5adSDave Gerlach emif_data->pm_data.regs_virt = 1388428e5adSDave Gerlach (struct emif_regs_amx3 *)emif_data->ti_emif_sram_data_virt; 1398428e5adSDave Gerlach emif_data->pm_data.regs_phys = emif_data->ti_emif_sram_data_phys; 1408428e5adSDave Gerlach 1418428e5adSDave Gerlach return 0; 1428428e5adSDave Gerlach 1438428e5adSDave Gerlach err_free_sram_code: 1448428e5adSDave Gerlach gen_pool_free(emif_data->sram_pool_code, emif_data->ti_emif_sram_virt, 1458428e5adSDave Gerlach ti_emif_sram_sz); 1468428e5adSDave Gerlach return ret; 1478428e5adSDave Gerlach } 1488428e5adSDave Gerlach 1498428e5adSDave Gerlach static int ti_emif_push_sram(struct device *dev, struct ti_emif_data *emif_data) 1508428e5adSDave Gerlach { 1518428e5adSDave Gerlach void *copy_addr; 1528428e5adSDave Gerlach u32 data_addr; 1538428e5adSDave Gerlach 1548428e5adSDave Gerlach copy_addr = sram_exec_copy(emif_data->sram_pool_code, 1558428e5adSDave Gerlach (void *)emif_data->ti_emif_sram_virt, 1568428e5adSDave Gerlach &ti_emif_sram, ti_emif_sram_sz); 1578428e5adSDave Gerlach if (!copy_addr) { 1588428e5adSDave Gerlach dev_err(dev, "Cannot copy emif code to sram\n"); 1598428e5adSDave Gerlach return -ENODEV; 1608428e5adSDave Gerlach } 1618428e5adSDave Gerlach 1628428e5adSDave Gerlach data_addr = sram_suspend_address(emif_data, 1638428e5adSDave Gerlach (unsigned long)&ti_emif_pm_sram_data); 1648428e5adSDave Gerlach copy_addr = sram_exec_copy(emif_data->sram_pool_code, 1658428e5adSDave Gerlach (void *)data_addr, 1668428e5adSDave Gerlach &emif_data->pm_data, 1678428e5adSDave Gerlach sizeof(emif_data->pm_data)); 1688428e5adSDave Gerlach if (!copy_addr) { 1698428e5adSDave Gerlach dev_err(dev, "Cannot copy emif data to code sram\n"); 1708428e5adSDave Gerlach return -ENODEV; 1718428e5adSDave Gerlach } 1728428e5adSDave Gerlach 1738428e5adSDave Gerlach return 0; 1748428e5adSDave Gerlach } 1758428e5adSDave Gerlach 1768428e5adSDave Gerlach /* 1778428e5adSDave Gerlach * Due to Usage Note 3.1.2 "DDR3: JEDEC Compliance for Maximum 1788428e5adSDave Gerlach * Self-Refresh Command Limit" found in AM335x Silicon Errata 1798428e5adSDave Gerlach * (Document SPRZ360F Revised November 2013) we must configure 1808428e5adSDave Gerlach * the self refresh delay timer to 0xA (8192 cycles) to avoid 1818428e5adSDave Gerlach * generating too many refresh command from the EMIF. 1828428e5adSDave Gerlach */ 1838428e5adSDave Gerlach static void ti_emif_configure_sr_delay(struct ti_emif_data *emif_data) 1848428e5adSDave Gerlach { 1858428e5adSDave Gerlach writel(EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES, 1868428e5adSDave Gerlach (emif_data->pm_data.ti_emif_base_addr_virt + 1878428e5adSDave Gerlach EMIF_POWER_MANAGEMENT_CONTROL)); 1888428e5adSDave Gerlach 1898428e5adSDave Gerlach writel(EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES, 1908428e5adSDave Gerlach (emif_data->pm_data.ti_emif_base_addr_virt + 1918428e5adSDave Gerlach EMIF_POWER_MANAGEMENT_CTRL_SHDW)); 1928428e5adSDave Gerlach } 1938428e5adSDave Gerlach 1948428e5adSDave Gerlach /** 1958428e5adSDave Gerlach * ti_emif_copy_pm_function_table - copy mapping of pm funcs in sram 1968428e5adSDave Gerlach * @sram_pool: pointer to struct gen_pool where dst resides 1978428e5adSDave Gerlach * @dst: void * to address that table should be copied 1988428e5adSDave Gerlach * 1998428e5adSDave Gerlach * Returns 0 if success other error code if table is not available 2008428e5adSDave Gerlach */ 2018428e5adSDave Gerlach int ti_emif_copy_pm_function_table(struct gen_pool *sram_pool, void *dst) 2028428e5adSDave Gerlach { 2038428e5adSDave Gerlach void *copy_addr; 2048428e5adSDave Gerlach 2058428e5adSDave Gerlach if (!emif_instance) 2068428e5adSDave Gerlach return -ENODEV; 2078428e5adSDave Gerlach 2088428e5adSDave Gerlach copy_addr = sram_exec_copy(sram_pool, dst, 2098428e5adSDave Gerlach &emif_instance->pm_functions, 2108428e5adSDave Gerlach sizeof(emif_instance->pm_functions)); 2118428e5adSDave Gerlach if (!copy_addr) 2128428e5adSDave Gerlach return -ENODEV; 2138428e5adSDave Gerlach 2148428e5adSDave Gerlach return 0; 2158428e5adSDave Gerlach } 2168428e5adSDave Gerlach EXPORT_SYMBOL_GPL(ti_emif_copy_pm_function_table); 2178428e5adSDave Gerlach 2188428e5adSDave Gerlach /** 2198428e5adSDave Gerlach * ti_emif_get_mem_type - return type for memory type in use 2208428e5adSDave Gerlach * 2218428e5adSDave Gerlach * Returns memory type value read from EMIF or error code if fails 2228428e5adSDave Gerlach */ 2238428e5adSDave Gerlach int ti_emif_get_mem_type(void) 2248428e5adSDave Gerlach { 2258428e5adSDave Gerlach unsigned long temp; 2268428e5adSDave Gerlach 2278428e5adSDave Gerlach if (!emif_instance) 2288428e5adSDave Gerlach return -ENODEV; 2298428e5adSDave Gerlach 2308428e5adSDave Gerlach temp = readl(emif_instance->pm_data.ti_emif_base_addr_virt + 2318428e5adSDave Gerlach EMIF_SDRAM_CONFIG); 2328428e5adSDave Gerlach 2338428e5adSDave Gerlach temp = (temp & SDRAM_TYPE_MASK) >> SDRAM_TYPE_SHIFT; 2348428e5adSDave Gerlach return temp; 2358428e5adSDave Gerlach } 2368428e5adSDave Gerlach EXPORT_SYMBOL_GPL(ti_emif_get_mem_type); 2378428e5adSDave Gerlach 2388428e5adSDave Gerlach static const struct of_device_id ti_emif_of_match[] = { 2398428e5adSDave Gerlach { .compatible = "ti,emif-am3352", .data = 2408428e5adSDave Gerlach (void *)EMIF_SRAM_AM33_REG_LAYOUT, }, 2418428e5adSDave Gerlach { .compatible = "ti,emif-am4372", .data = 2428428e5adSDave Gerlach (void *)EMIF_SRAM_AM43_REG_LAYOUT, }, 2438428e5adSDave Gerlach {}, 2448428e5adSDave Gerlach }; 2458428e5adSDave Gerlach MODULE_DEVICE_TABLE(of, ti_emif_of_match); 2468428e5adSDave Gerlach 24738853979SDave Gerlach #ifdef CONFIG_PM_SLEEP 24838853979SDave Gerlach static int ti_emif_resume(struct device *dev) 24938853979SDave Gerlach { 25038853979SDave Gerlach unsigned long tmp = 25196424aa9SKrzysztof Kozlowski __raw_readl((void __iomem *)emif_instance->ti_emif_sram_virt); 25238853979SDave Gerlach 25338853979SDave Gerlach /* 25438853979SDave Gerlach * Check to see if what we are copying is already present in the 25538853979SDave Gerlach * first byte at the destination, only copy if it is not which 25638853979SDave Gerlach * indicates we have lost context and sram no longer contains 25738853979SDave Gerlach * the PM code 25838853979SDave Gerlach */ 25938853979SDave Gerlach if (tmp != ti_emif_sram) 26038853979SDave Gerlach ti_emif_push_sram(dev, emif_instance); 26138853979SDave Gerlach 26238853979SDave Gerlach return 0; 26338853979SDave Gerlach } 26438853979SDave Gerlach 26538853979SDave Gerlach static int ti_emif_suspend(struct device *dev) 26638853979SDave Gerlach { 26738853979SDave Gerlach /* 26838853979SDave Gerlach * The contents will be present in DDR hence no need to 26938853979SDave Gerlach * explicitly save 27038853979SDave Gerlach */ 27138853979SDave Gerlach return 0; 27238853979SDave Gerlach } 27338853979SDave Gerlach #endif /* CONFIG_PM_SLEEP */ 27438853979SDave Gerlach 2758428e5adSDave Gerlach static int ti_emif_probe(struct platform_device *pdev) 2768428e5adSDave Gerlach { 2778428e5adSDave Gerlach int ret; 2788428e5adSDave Gerlach struct resource *res; 2798428e5adSDave Gerlach struct device *dev = &pdev->dev; 2808428e5adSDave Gerlach const struct of_device_id *match; 2818428e5adSDave Gerlach struct ti_emif_data *emif_data; 2828428e5adSDave Gerlach 2838428e5adSDave Gerlach emif_data = devm_kzalloc(dev, sizeof(*emif_data), GFP_KERNEL); 2848428e5adSDave Gerlach if (!emif_data) 2858428e5adSDave Gerlach return -ENOMEM; 2868428e5adSDave Gerlach 2878428e5adSDave Gerlach match = of_match_device(ti_emif_of_match, &pdev->dev); 2888428e5adSDave Gerlach if (!match) 2898428e5adSDave Gerlach return -ENODEV; 2908428e5adSDave Gerlach 2918428e5adSDave Gerlach emif_data->pm_data.ti_emif_sram_config = (unsigned long)match->data; 2928428e5adSDave Gerlach 2938428e5adSDave Gerlach res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2948428e5adSDave Gerlach emif_data->pm_data.ti_emif_base_addr_virt = devm_ioremap_resource(dev, 2958428e5adSDave Gerlach res); 2968428e5adSDave Gerlach if (IS_ERR(emif_data->pm_data.ti_emif_base_addr_virt)) { 2978428e5adSDave Gerlach ret = PTR_ERR(emif_data->pm_data.ti_emif_base_addr_virt); 2988428e5adSDave Gerlach return ret; 2998428e5adSDave Gerlach } 3008428e5adSDave Gerlach 3018428e5adSDave Gerlach emif_data->pm_data.ti_emif_base_addr_phys = res->start; 3028428e5adSDave Gerlach 3038428e5adSDave Gerlach ti_emif_configure_sr_delay(emif_data); 3048428e5adSDave Gerlach 3058428e5adSDave Gerlach ret = ti_emif_alloc_sram(dev, emif_data); 3068428e5adSDave Gerlach if (ret) 3078428e5adSDave Gerlach return ret; 3088428e5adSDave Gerlach 3098428e5adSDave Gerlach ret = ti_emif_push_sram(dev, emif_data); 3108428e5adSDave Gerlach if (ret) 3118428e5adSDave Gerlach goto fail_free_sram; 3128428e5adSDave Gerlach 3138428e5adSDave Gerlach emif_instance = emif_data; 3148428e5adSDave Gerlach 3158428e5adSDave Gerlach return 0; 3168428e5adSDave Gerlach 3178428e5adSDave Gerlach fail_free_sram: 3188428e5adSDave Gerlach ti_emif_free_sram(emif_data); 3198428e5adSDave Gerlach 3208428e5adSDave Gerlach return ret; 3218428e5adSDave Gerlach } 3228428e5adSDave Gerlach 3238428e5adSDave Gerlach static int ti_emif_remove(struct platform_device *pdev) 3248428e5adSDave Gerlach { 3258428e5adSDave Gerlach struct ti_emif_data *emif_data = emif_instance; 3268428e5adSDave Gerlach 3278428e5adSDave Gerlach emif_instance = NULL; 3288428e5adSDave Gerlach 3298428e5adSDave Gerlach ti_emif_free_sram(emif_data); 3308428e5adSDave Gerlach 3318428e5adSDave Gerlach return 0; 3328428e5adSDave Gerlach } 3338428e5adSDave Gerlach 33438853979SDave Gerlach static const struct dev_pm_ops ti_emif_pm_ops = { 33538853979SDave Gerlach SET_SYSTEM_SLEEP_PM_OPS(ti_emif_suspend, ti_emif_resume) 33638853979SDave Gerlach }; 33738853979SDave Gerlach 3388428e5adSDave Gerlach static struct platform_driver ti_emif_driver = { 3398428e5adSDave Gerlach .probe = ti_emif_probe, 3408428e5adSDave Gerlach .remove = ti_emif_remove, 3418428e5adSDave Gerlach .driver = { 3428428e5adSDave Gerlach .name = KBUILD_MODNAME, 343*62c290a6SKrzysztof Kozlowski .of_match_table = ti_emif_of_match, 34438853979SDave Gerlach .pm = &ti_emif_pm_ops, 3458428e5adSDave Gerlach }, 3468428e5adSDave Gerlach }; 3478428e5adSDave Gerlach module_platform_driver(ti_emif_driver); 3488428e5adSDave Gerlach 3498428e5adSDave Gerlach MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>"); 3508428e5adSDave Gerlach MODULE_DESCRIPTION("Texas Instruments SRAM EMIF driver"); 3518428e5adSDave Gerlach MODULE_LICENSE("GPL v2"); 352