From 27ecd5d8f3f7a571f6ce8080769e8b1883e49cf1 Mon Sep 17 00:00:00 2001 From: Jorge Ramirez-Ortiz Date: Fri, 21 Oct 2016 10:58:53 +0200 Subject: [PATCH] drivers: flash: SoC KSDK This KSDK flash shim driver supports the device in the FRDM K64F platform (enabled with this commit). WARNING: the driver disables the system interrupts for potentially long periods of time. This is required to avoid Read-While-Write issues since most platforms run in XIP mode. For more detailed information see the link below: http://cache.freescale.com/files/32bit/doc/app_note/AN4695.pdf Change-Id: I70f8d09080251033ce2f45be0c2eb95c19fded08 Signed-off-by: Jorge Ramirez-Ortiz --- .../nxp_kinetis/k6x/Kconfig.defconfig.mk64f12 | 7 + drivers/flash/Kconfig | 18 +++ drivers/flash/Makefile | 1 + drivers/flash/soc_flash_ksdk.c | 120 ++++++++++++++++++ ext/hal/ksdk/drivers/Makefile | 2 + 5 files changed, 148 insertions(+) create mode 100644 drivers/flash/soc_flash_ksdk.c diff --git a/arch/arm/soc/nxp_kinetis/k6x/Kconfig.defconfig.mk64f12 b/arch/arm/soc/nxp_kinetis/k6x/Kconfig.defconfig.mk64f12 index a3ab3e2620d..c196ca5f24b 100644 --- a/arch/arm/soc/nxp_kinetis/k6x/Kconfig.defconfig.mk64f12 +++ b/arch/arm/soc/nxp_kinetis/k6x/Kconfig.defconfig.mk64f12 @@ -77,4 +77,11 @@ config RANDOM_KSDK endif # RANDOM_GENERATOR +if FLASH + +config SOC_FLASH_KSDK + def_bool y + +endif # FLASH + endif # SOC_MK64F12 diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index b2d196c9c86..ef00c45d4b8 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -132,6 +132,24 @@ config SOC_FLASH_NRF5_DEV_NAME help Specify the device name for the flash driver. +config SOC_FLASH_KSDK + bool "KSDK flash shim driver" + depends on FLASH && HAS_KSDK + default n + help + Enables the KSDK flash shim driver. + WARNING: This driver will disable the system interrupts for + the duration of the flash erase/write operations. This will + have an impact on the overall system performance - whether + this is acceptable or not will depend on the use case. + +config SOC_FLASH_KSDK_DEV_NAME + string "KSDK flash device name" + depends on SOC_FLASH_KSDK + default "KSDK_FLASH" + help + Specify the device name for the flash driver. + config SOC_FLASH_QMSI_API_REENTRANCY bool prompt "flash driver API reentrancy for QMSI shim driver" diff --git a/drivers/flash/Makefile b/drivers/flash/Makefile index 47d1c7914f7..f5123c56586 100644 --- a/drivers/flash/Makefile +++ b/drivers/flash/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_SPI_FLASH_W25QXXDV) += spi_flash_w25qxxdv.o obj-$(CONFIG_SOC_FLASH_QMSI) += soc_flash_qmsi.o obj-$(CONFIG_SOC_FLASH_NRF5) += soc_flash_nrf5.o +obj-$(CONFIG_SOC_FLASH_KSDK) += soc_flash_ksdk.o diff --git a/drivers/flash/soc_flash_ksdk.c b/drivers/flash/soc_flash_ksdk.c new file mode 100644 index 00000000000..7673cf1512c --- /dev/null +++ b/drivers/flash/soc_flash_ksdk.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2016 Linaro Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsl_common.h" +#include "fsl_flash.h" + +struct flash_priv { + flash_config_t config; +}; + +/* + * Interrupt vectors could be executed from flash hence the need for locking. + * The underlying KDSK driver takes care of copying the functions to SRAM. + * + * For more information, see the application note below on Read-While-Write + * http://cache.freescale.com/files/32bit/doc/app_note/AN4695.pdf + * + */ + +static int flash_ksdk_erase(struct device *dev, off_t offset, size_t len) +{ + struct flash_priv *priv = dev->driver_data; + uint32_t addr; + status_t rc; + int key; + + addr = offset + priv->config.PFlashBlockBase; + + key = irq_lock(); + rc = FLASH_Erase(&priv->config, addr, len, kFLASH_apiEraseKey); + irq_unlock(key); + + return (rc == kStatus_Success) ? 0 : -EINVAL; +} + +static int flash_ksdk_read(struct device *dev, off_t offset, + void *data, size_t len) +{ + struct flash_priv *priv = dev->driver_data; + uint32_t addr; + + /* + * The KSDK supports different flash chips whose valid ranges are + * hidden below the API: until the API export these ranges, we can not + * do any generic validation + */ + addr = offset + priv->config.PFlashBlockBase; + + memcpy(data, (void *) addr, len); + + return 0; +} + +static int flash_ksdk_write(struct device *dev, off_t offset, + const void *data, size_t len) +{ + struct flash_priv *priv = dev->driver_data; + uint32_t addr; + status_t rc; + int key; + + addr = offset + priv->config.PFlashBlockBase; + + key = irq_lock(); + rc = FLASH_Program(&priv->config, addr, (uint32_t *) data, len); + irq_unlock(key); + + return (rc == kStatus_Success) ? 0 : -EINVAL; +} + +static int flash_ksdk_write_protection(struct device *dev, bool enable) +{ + return -EIO; +} + +static struct flash_priv flash_data; + +static const struct flash_driver_api flash_ksdk_api = { + .write_protection = flash_ksdk_write_protection, + .erase = flash_ksdk_erase, + .write = flash_ksdk_write, + .read = flash_ksdk_read, +}; + +static int flash_ksdk_init(struct device *dev) +{ + struct flash_priv *priv = dev->driver_data; + status_t rc; + + rc = FLASH_Init(&priv->config); + + return (rc == kStatus_Success) ? 0 : -EIO; +} + +DEVICE_AND_API_INIT(flash_ksdk, CONFIG_SOC_FLASH_KSDK_DEV_NAME, + flash_ksdk_init, &flash_data, NULL, SECONDARY, + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &flash_ksdk_api); + diff --git a/ext/hal/ksdk/drivers/Makefile b/ext/hal/ksdk/drivers/Makefile index 07fe7bf2d22..376fe4c8309 100644 --- a/ext/hal/ksdk/drivers/Makefile +++ b/ext/hal/ksdk/drivers/Makefile @@ -17,3 +17,5 @@ obj-$(CONFIG_ETH_KSDK) += fsl_enet.o obj-$(CONFIG_I2C_KSDK) += fsl_i2c.o obj-$(CONFIG_RANDOM_KSDK) += fsl_rnga.o +obj-$(CONFIG_SOC_FLASH_KSDK) += fsl_flash.o +