345 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * TI AM33XX SRAM EMIF Driver4 *5 * Copyright (C) 2016-2017 Texas Instruments Inc.6 * Dave Gerlach7 */8 9#include <linux/err.h>10#include <linux/genalloc.h>11#include <linux/io.h>12#include <linux/kernel.h>13#include <linux/module.h>14#include <linux/of.h>15#include <linux/of_platform.h>16#include <linux/platform_device.h>17#include <linux/sram.h>18#include <linux/ti-emif-sram.h>19 20#include "emif.h"21 22#define TI_EMIF_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \23 (unsigned long)&ti_emif_sram)24 25#define EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES 0x00a026 27struct ti_emif_data {28 phys_addr_t ti_emif_sram_phys;29 phys_addr_t ti_emif_sram_data_phys;30 unsigned long ti_emif_sram_virt;31 unsigned long ti_emif_sram_data_virt;32 struct gen_pool *sram_pool_code;33 struct gen_pool *sram_pool_data;34 struct ti_emif_pm_data pm_data;35 struct ti_emif_pm_functions pm_functions;36};37 38static struct ti_emif_data *emif_instance;39 40static u32 sram_suspend_address(struct ti_emif_data *emif_data,41 unsigned long addr)42{43 return (emif_data->ti_emif_sram_virt +44 TI_EMIF_SRAM_SYMBOL_OFFSET(addr));45}46 47static phys_addr_t sram_resume_address(struct ti_emif_data *emif_data,48 unsigned long addr)49{50 return ((unsigned long)emif_data->ti_emif_sram_phys +51 TI_EMIF_SRAM_SYMBOL_OFFSET(addr));52}53 54static void ti_emif_free_sram(struct ti_emif_data *emif_data)55{56 gen_pool_free(emif_data->sram_pool_code, emif_data->ti_emif_sram_virt,57 ti_emif_sram_sz);58 gen_pool_free(emif_data->sram_pool_data,59 emif_data->ti_emif_sram_data_virt,60 sizeof(struct emif_regs_amx3));61}62 63static int ti_emif_alloc_sram(struct device *dev,64 struct ti_emif_data *emif_data)65{66 struct device_node *np = dev->of_node;67 int ret;68 69 emif_data->sram_pool_code = of_gen_pool_get(np, "sram", 0);70 if (!emif_data->sram_pool_code) {71 dev_err(dev, "Unable to get sram pool for ocmcram code\n");72 return -ENODEV;73 }74 75 emif_data->ti_emif_sram_virt =76 gen_pool_alloc(emif_data->sram_pool_code,77 ti_emif_sram_sz);78 if (!emif_data->ti_emif_sram_virt) {79 dev_err(dev, "Unable to allocate code memory from ocmcram\n");80 return -ENOMEM;81 }82 83 /* Save physical address to calculate resume offset during pm init */84 emif_data->ti_emif_sram_phys =85 gen_pool_virt_to_phys(emif_data->sram_pool_code,86 emif_data->ti_emif_sram_virt);87 88 /* Get sram pool for data section and allocate space */89 emif_data->sram_pool_data = of_gen_pool_get(np, "sram", 1);90 if (!emif_data->sram_pool_data) {91 dev_err(dev, "Unable to get sram pool for ocmcram data\n");92 ret = -ENODEV;93 goto err_free_sram_code;94 }95 96 emif_data->ti_emif_sram_data_virt =97 gen_pool_alloc(emif_data->sram_pool_data,98 sizeof(struct emif_regs_amx3));99 if (!emif_data->ti_emif_sram_data_virt) {100 dev_err(dev, "Unable to allocate data memory from ocmcram\n");101 ret = -ENOMEM;102 goto err_free_sram_code;103 }104 105 /* Save physical address to calculate resume offset during pm init */106 emif_data->ti_emif_sram_data_phys =107 gen_pool_virt_to_phys(emif_data->sram_pool_data,108 emif_data->ti_emif_sram_data_virt);109 /*110 * These functions are called during suspend path while MMU is111 * still on so add virtual base to offset for absolute address112 */113 emif_data->pm_functions.save_context =114 sram_suspend_address(emif_data,115 (unsigned long)ti_emif_save_context);116 emif_data->pm_functions.enter_sr =117 sram_suspend_address(emif_data,118 (unsigned long)ti_emif_enter_sr);119 emif_data->pm_functions.abort_sr =120 sram_suspend_address(emif_data,121 (unsigned long)ti_emif_abort_sr);122 123 /*124 * These are called during resume path when MMU is not enabled125 * so physical address is used instead126 */127 emif_data->pm_functions.restore_context =128 sram_resume_address(emif_data,129 (unsigned long)ti_emif_restore_context);130 emif_data->pm_functions.exit_sr =131 sram_resume_address(emif_data,132 (unsigned long)ti_emif_exit_sr);133 emif_data->pm_functions.run_hw_leveling =134 sram_resume_address(emif_data,135 (unsigned long)ti_emif_run_hw_leveling);136 137 emif_data->pm_data.regs_virt =138 (struct emif_regs_amx3 *)emif_data->ti_emif_sram_data_virt;139 emif_data->pm_data.regs_phys = emif_data->ti_emif_sram_data_phys;140 141 return 0;142 143err_free_sram_code:144 gen_pool_free(emif_data->sram_pool_code, emif_data->ti_emif_sram_virt,145 ti_emif_sram_sz);146 return ret;147}148 149static int ti_emif_push_sram(struct device *dev, struct ti_emif_data *emif_data)150{151 void *copy_addr;152 u32 data_addr;153 154 copy_addr = sram_exec_copy(emif_data->sram_pool_code,155 (void *)emif_data->ti_emif_sram_virt,156 &ti_emif_sram, ti_emif_sram_sz);157 if (!copy_addr) {158 dev_err(dev, "Cannot copy emif code to sram\n");159 return -ENODEV;160 }161 162 data_addr = sram_suspend_address(emif_data,163 (unsigned long)&ti_emif_pm_sram_data);164 copy_addr = sram_exec_copy(emif_data->sram_pool_code,165 (void *)data_addr,166 &emif_data->pm_data,167 sizeof(emif_data->pm_data));168 if (!copy_addr) {169 dev_err(dev, "Cannot copy emif data to code sram\n");170 return -ENODEV;171 }172 173 return 0;174}175 176/*177 * Due to Usage Note 3.1.2 "DDR3: JEDEC Compliance for Maximum178 * Self-Refresh Command Limit" found in AM335x Silicon Errata179 * (Document SPRZ360F Revised November 2013) we must configure180 * the self refresh delay timer to 0xA (8192 cycles) to avoid181 * generating too many refresh command from the EMIF.182 */183static void ti_emif_configure_sr_delay(struct ti_emif_data *emif_data)184{185 writel(EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES,186 (emif_data->pm_data.ti_emif_base_addr_virt +187 EMIF_POWER_MANAGEMENT_CONTROL));188 189 writel(EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES,190 (emif_data->pm_data.ti_emif_base_addr_virt +191 EMIF_POWER_MANAGEMENT_CTRL_SHDW));192}193 194/**195 * ti_emif_copy_pm_function_table - copy mapping of pm funcs in sram196 * @sram_pool: pointer to struct gen_pool where dst resides197 * @dst: void * to address that table should be copied198 *199 * Returns 0 if success other error code if table is not available200 */201int ti_emif_copy_pm_function_table(struct gen_pool *sram_pool, void *dst)202{203 void *copy_addr;204 205 if (!emif_instance)206 return -ENODEV;207 208 copy_addr = sram_exec_copy(sram_pool, dst,209 &emif_instance->pm_functions,210 sizeof(emif_instance->pm_functions));211 if (!copy_addr)212 return -ENODEV;213 214 return 0;215}216EXPORT_SYMBOL_GPL(ti_emif_copy_pm_function_table);217 218/**219 * ti_emif_get_mem_type - return type for memory type in use220 *221 * Returns memory type value read from EMIF or error code if fails222 */223int ti_emif_get_mem_type(void)224{225 unsigned long temp;226 227 if (!emif_instance)228 return -ENODEV;229 230 temp = readl(emif_instance->pm_data.ti_emif_base_addr_virt +231 EMIF_SDRAM_CONFIG);232 233 temp = (temp & SDRAM_TYPE_MASK) >> SDRAM_TYPE_SHIFT;234 return temp;235}236EXPORT_SYMBOL_GPL(ti_emif_get_mem_type);237 238static const struct of_device_id ti_emif_of_match[] = {239 { .compatible = "ti,emif-am3352", .data =240 (void *)EMIF_SRAM_AM33_REG_LAYOUT, },241 { .compatible = "ti,emif-am4372", .data =242 (void *)EMIF_SRAM_AM43_REG_LAYOUT, },243 {},244};245MODULE_DEVICE_TABLE(of, ti_emif_of_match);246 247#ifdef CONFIG_PM_SLEEP248static int ti_emif_resume(struct device *dev)249{250 unsigned long tmp =251 __raw_readl((void __iomem *)emif_instance->ti_emif_sram_virt);252 253 /*254 * Check to see if what we are copying is already present in the255 * first byte at the destination, only copy if it is not which256 * indicates we have lost context and sram no longer contains257 * the PM code258 */259 if (tmp != ti_emif_sram)260 ti_emif_push_sram(dev, emif_instance);261 262 return 0;263}264 265static int ti_emif_suspend(struct device *dev)266{267 /*268 * The contents will be present in DDR hence no need to269 * explicitly save270 */271 return 0;272}273#endif /* CONFIG_PM_SLEEP */274 275static int ti_emif_probe(struct platform_device *pdev)276{277 int ret;278 struct resource *res;279 struct device *dev = &pdev->dev;280 struct ti_emif_data *emif_data;281 282 emif_data = devm_kzalloc(dev, sizeof(*emif_data), GFP_KERNEL);283 if (!emif_data)284 return -ENOMEM;285 286 emif_data->pm_data.ti_emif_sram_config = (unsigned long) device_get_match_data(&pdev->dev);287 288 emif_data->pm_data.ti_emif_base_addr_virt = devm_platform_get_and_ioremap_resource(pdev,289 0,290 &res);291 if (IS_ERR(emif_data->pm_data.ti_emif_base_addr_virt)) {292 ret = PTR_ERR(emif_data->pm_data.ti_emif_base_addr_virt);293 return ret;294 }295 296 emif_data->pm_data.ti_emif_base_addr_phys = res->start;297 298 ti_emif_configure_sr_delay(emif_data);299 300 ret = ti_emif_alloc_sram(dev, emif_data);301 if (ret)302 return ret;303 304 ret = ti_emif_push_sram(dev, emif_data);305 if (ret)306 goto fail_free_sram;307 308 emif_instance = emif_data;309 310 return 0;311 312fail_free_sram:313 ti_emif_free_sram(emif_data);314 315 return ret;316}317 318static void ti_emif_remove(struct platform_device *pdev)319{320 struct ti_emif_data *emif_data = emif_instance;321 322 emif_instance = NULL;323 324 ti_emif_free_sram(emif_data);325}326 327static const struct dev_pm_ops ti_emif_pm_ops = {328 SET_SYSTEM_SLEEP_PM_OPS(ti_emif_suspend, ti_emif_resume)329};330 331static struct platform_driver ti_emif_driver = {332 .probe = ti_emif_probe,333 .remove_new = ti_emif_remove,334 .driver = {335 .name = KBUILD_MODNAME,336 .of_match_table = ti_emif_of_match,337 .pm = &ti_emif_pm_ops,338 },339};340module_platform_driver(ti_emif_driver);341 342MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>");343MODULE_DESCRIPTION("Texas Instruments SRAM EMIF driver");344MODULE_LICENSE("GPL v2");345