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