diff --git a/arch/arm/src/cxd56xx/Kconfig b/arch/arm/src/cxd56xx/Kconfig index 474934ac08..04132ad1e3 100644 --- a/arch/arm/src/cxd56xx/Kconfig +++ b/arch/arm/src/cxd56xx/Kconfig @@ -45,6 +45,10 @@ config CXD56_XOSC_CLOCK int default 26000000 +config CXD56_SPH + bool + default y if ASMP + config CXD56_PMIC bool default y diff --git a/arch/arm/src/cxd56xx/Make.defs b/arch/arm/src/cxd56xx/Make.defs index 34c56d3f73..3b0be40458 100644 --- a/arch/arm/src/cxd56xx/Make.defs +++ b/arch/arm/src/cxd56xx/Make.defs @@ -138,6 +138,10 @@ ifeq ($(CONFIG_CXD56_SFC),y) CHIP_CSRCS += cxd56_sfc.c endif +ifeq ($(CONFIG_CXD56_SPH),y) +CHIP_CSRCS += cxd56_sph.c +endif + ifeq ($(CONFIG_CXD56_EMMC),y) CHIP_CSRCS += cxd56_emmc.c endif diff --git a/arch/arm/src/cxd56xx/cxd56_sph.c b/arch/arm/src/cxd56xx/cxd56_sph.c new file mode 100644 index 0000000000..5ee5376d86 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_sph.c @@ -0,0 +1,321 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_sph.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "chip.h" + +#include "hardware/cxd56_sph.h" +#include "cxd56_sph.h" + +#ifdef CONFIG_CXD56_SPH + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CPU_ID (CXD56_CPU_BASE + 0x40) + +#define NR_HSEMS 16 + +#define sph_state_unlocked(sts) (STS_STATE(sts) == STATE_IDLE) +#define sph_state_locked(sts) (STS_STATE(sts) == STATE_LOCKED) +#define sph_state_busy(sts) (STS_STATE(sts) == STATE_LOCKEDANDRESERVED) + +#ifdef CONFIG_CXD56_SPH_DEBUG +# define hsinfo(fmt, ...) _info(fmt, ## __VA_ARGS__) +#else +# define hsinfo(fmt, ...) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct sph_dev_s +{ + int id; + sem_t wait; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int sph_open(FAR struct file *filep); +static int sph_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +static int sph_semtake(sem_t *id); +static void sph_semgive(sem_t *id); +static int sph_lock(FAR struct sph_dev_s *priv); +static int sph_trylock(FAR struct sph_dev_s *priv); +static inline int sph_unlock(FAR struct sph_dev_s *priv); +static int cxd56_sphirqhandler(int irq, FAR void *context, FAR void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations sph_fops = +{ + .open = sph_open, + .close = 0, + .read = 0, + .write = 0, + .seek = 0, + .ioctl = sph_ioctl, +}; + +static struct sph_dev_s g_sphdev[NR_HSEMS]; +static int g_cpuid; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int sph_open(FAR struct file *filep) +{ + /* Exclusive access */ + + if (filep->f_inode->i_crefs > 1) + { + return ERROR; + } + + return OK; +} + +static int sph_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct sph_dev_s *priv = + (FAR struct sph_dev_s *)filep->f_inode->i_private; + int ret = -ENOTTY; + + hsinfo("cmd = %x\n", cmd); + + if (!_HSIOCVALID(cmd)) + { + return ret; + } + + switch (cmd) + { + case HSLOCK: + ret = sph_lock(priv); + break; + + case HSUNLOCK: + ret = sph_unlock(priv); + break; + + case HSTRYLOCK: + ret = sph_trylock(priv); + break; + + default: + break; + } + + return ret; +} + +static int sph_semtake(sem_t *id) +{ + while (sem_wait(id) != 0) + { + ASSERT(errno == EINTR); + } + return OK; +} + +static void sph_semgive(sem_t *id) +{ + sem_post(id); +} + +static int sph_lock(FAR struct sph_dev_s *priv) +{ + uint32_t sts; + int ret; + + ret = sph_trylock(priv); + if (ret == OK) + { + return OK; + } + + for (; ; ) + { + putreg32(REQ_RESERVE, CXD56_SPH_REQ(priv->id)); + hsinfo("hsem%d is locked.\n", priv->id); + + sts = getreg32(CXD56_SPH_STS(priv->id)); + if (sph_state_busy(sts) && RESV_OWNER(sts) == g_cpuid) + { + /* If successfully reserved, wait for semaphore unlocked. */ + + sts = getreg32(CXD56_SPH_STS(priv->id)); + if (sph_state_busy(sts)) + { + sph_semtake(&priv->wait); + } + + /* Get latest status for determining locked owner. */ + + sts = getreg32(CXD56_SPH_STS(priv->id)); + } + + /* Confirm locked CPU is me. */ + + if (sph_state_locked(sts) && LOCK_OWNER(sts) == g_cpuid) + { + break; + } + } + + return OK; +} + +static int sph_trylock(FAR struct sph_dev_s *priv) +{ + uint32_t sts; + + sts = getreg32(CXD56_SPH_STS(priv->id)); + if (sph_state_unlocked(sts)) + { + putreg32(REQ_LOCK, CXD56_SPH_REQ(priv->id)); + hsinfo("hsem%d is locked.\n", priv->id); + + sts = getreg32(CXD56_SPH_STS(priv->id)); + if (sph_state_locked(sts) && LOCK_OWNER(sts) == g_cpuid) + { + return OK; + } + } + + return -EBUSY; +} + +static inline int sph_unlock(FAR struct sph_dev_s *priv) +{ + putreg32(REQ_UNLOCK, CXD56_SPH_REQ(priv->id)); + hsinfo("hsem%d is unlocked.\n", priv->id); + return OK; +} + +static inline int cxd56_sphdevinit(FAR const char *devname, int num) +{ + FAR struct sph_dev_s *priv = &g_sphdev[num]; + char fullpath[64]; + int ret; + + snprintf(fullpath, sizeof(fullpath), "/dev/%s%d", devname, num); + + ret = register_driver(fullpath, &sph_fops, 0666, (FAR void *)priv); + if (ret != 0) + { + return ERROR; + } + + sem_init(&priv->wait, 0, 0); + priv->id = num; + + irq_attach(CXD56_IRQ_SPH0 + num, cxd56_sphirqhandler, NULL); + up_enable_irq(CXD56_IRQ_SPH0 + num); + + return OK; +} + +static int cxd56_sphirqhandler(int irq, FAR void *context, FAR void *arg) +{ + int id; + + /* Calculate hardware semaphore ID from IRQ number */ + + id = irq - CXD56_IRQ_SPH0; + + DEBUGASSERT(id >= 0 && id <= 16); + + /* Clear interrupt */ + + putreg32(REQ_INTRCLR, CXD56_SPH_REQ(id)); + + /* Give semaphore for hardware semaphore is locked */ + + sph_semgive(&g_sphdev[id].wait); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int cxd56_sphinitialize(FAR const char *devname) +{ + int ret; + int i; + + /* No. 0-2 and 15 semaphores are reserved by other system. */ + + for (i = 3; i < 15; i++) + { + ret = cxd56_sphdevinit(devname, i); + if (ret != OK) + { + return ERROR; + } + } + + g_cpuid = getreg32(CPU_ID); + + return OK; +} + +#endif diff --git a/arch/arm/src/cxd56xx/cxd56_sph.h b/arch/arm/src/cxd56xx/cxd56_sph.h new file mode 100644 index 0000000000..aa926056ce --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_sph.h @@ -0,0 +1,65 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_sph.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_SPH_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_SPH_H + +#include + +#define _HSIOCVALID(c) (_IOC_TYPE(c)==0x7f00) +#define _HSIOC(nr) _IOC(0x7f00,nr) + +#define HSLOCK _HSIOC(0x01) +#define HSTRYLOCK _HSIOC(0x02) +#define HSUNLOCK _HSIOC(0x03) + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +int cxd56_sphinitialize(FAR const char *devname); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_SPH_H */ diff --git a/arch/arm/src/cxd56xx/hardware/cxd56_sph.h b/arch/arm/src/cxd56xx/hardware/cxd56_sph.h new file mode 100644 index 0000000000..7f0f5eacbd --- /dev/null +++ b/arch/arm/src/cxd56xx/hardware/cxd56_sph.h @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/hardware/cxd56_sph.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_HARDWARE_CXD56_SPH_H +#define __ARCH_ARM_SRC_CXD56XX_HARDWARE_CXD56_SPH_H + +/***************************************************************************** + * Included Files + *****************************************************************************/ + +#include "chip.h" + +/***************************************************************************** + * Pre-processor Definitions + *****************************************************************************/ + +#define CXD56_SPH_REQ(n) (CXD56_SPH_BASE + ((n) * 16) + 0) +#define CXD56_SPH_STS(n) (CXD56_SPH_BASE + ((n) * 16) + 4) +#define CXD56_SPH_RESET(n) (CXD56_SPH_BASE + ((n) * 4)) + +/* Hardware semaphore request */ + +#define REQ_UNLOCK 0 +#define REQ_LOCK 1 +#define REQ_RESERVE 2 +#define REQ_INTRCLR 3 + +/* Hardware semaphore status [3:0] */ + +#define STATE_IDLE 0 +#define STATE_LOCKED 1 +#define STATE_LOCKEDANDRESERVED 2 + +#define STS_STATE(sts) ((sts) & 0xf) +#define LOCK_OWNER(sts) (((sts) >> 16) & 0x1f) +#define RESV_OWNER(sts) (((sts) >> 24) & 0x1f) + +#endif diff --git a/boards/arm/cxd56xx/common/src/Make.defs b/boards/arm/cxd56xx/common/src/Make.defs index 0e8a37acda..6b917af5b5 100644 --- a/boards/arm/cxd56xx/common/src/Make.defs +++ b/boards/arm/cxd56xx/common/src/Make.defs @@ -32,6 +32,12 @@ # ############################################################################ +CSRCS += cxd56_boot.c + +ifeq ($(CONFIG_BOARDCTL_UNIQUEID),y) +CSRCS += cxd56_uid.c +endif + ifeq ($(CONFIG_CXD56_BACKUPLOG),y) CSRCS += cxd56_crashdump.c endif @@ -120,6 +126,18 @@ ifeq ($(CONFIG_LCD_LPM013M091A),y) CSRCS += cxd56_lpm013m091a.c endif +ifeq ($(CONFIG_CXD56_SFC),y) +CSRCS += cxd56_flash.c +endif + +ifeq ($(CONFIG_USBMSC),y) +CSRCS += cxd56_usbmsc.c +endif + +ifeq ($(CONFIG_CXD56_I2C_DRIVER),y) +CSRCS += cxd56_i2cdev.c +endif + DEPPATH += --dep-path src VPATH += :src CFLAGS += $(shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src) diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_boot.c b/boards/arm/cxd56xx/common/src/cxd56_boot.c similarity index 98% rename from boards/arm/cxd56xx/spresense/src/cxd56_boot.c rename to boards/arm/cxd56xx/common/src/cxd56_boot.c index caaa719cdc..e58220bf37 100644 --- a/boards/arm/cxd56xx/spresense/src/cxd56_boot.c +++ b/boards/arm/cxd56xx/common/src/cxd56_boot.c @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/arm/cxd56xx/spresense/src/cxd56_boot.c + * boards/arm/cxd56xx/common/src/cxd56_boot.c * * Copyright 2018 Sony Semiconductor Solutions Corporation * diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_flash.c b/boards/arm/cxd56xx/common/src/cxd56_flash.c similarity index 98% rename from boards/arm/cxd56xx/spresense/src/cxd56_flash.c rename to boards/arm/cxd56xx/common/src/cxd56_flash.c index 26acc0dc80..856d16cebc 100644 --- a/boards/arm/cxd56xx/spresense/src/cxd56_flash.c +++ b/boards/arm/cxd56xx/common/src/cxd56_flash.c @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/arm/cxd56xx/spresense/src/cxd56_flash.c + * boards/arm/cxd56xx/common/src/cxd56_flash.c * * Copyright 2018 Sony Semiconductor Solutions Corporation * diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_i2cdev.c b/boards/arm/cxd56xx/common/src/cxd56_i2cdev.c similarity index 98% rename from boards/arm/cxd56xx/spresense/src/cxd56_i2cdev.c rename to boards/arm/cxd56xx/common/src/cxd56_i2cdev.c index 4a144f59f7..4b1f202099 100644 --- a/boards/arm/cxd56xx/spresense/src/cxd56_i2cdev.c +++ b/boards/arm/cxd56xx/common/src/cxd56_i2cdev.c @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/arm/cxd56xx/spresense/src/cxd56_i2cdev.c + * boards/arm/cxd56xx/common/src/cxd56_i2cdev.c * * Copyright 2018 Sony Semiconductor Solutions Corporation * diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_uid.c b/boards/arm/cxd56xx/common/src/cxd56_uid.c similarity index 98% rename from boards/arm/cxd56xx/spresense/src/cxd56_uid.c rename to boards/arm/cxd56xx/common/src/cxd56_uid.c index 05e4638af5..3d188db2df 100644 --- a/boards/arm/cxd56xx/spresense/src/cxd56_uid.c +++ b/boards/arm/cxd56xx/common/src/cxd56_uid.c @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/arm/cxd56xx/spresense/src/cxd56_uid.c + * boards/arm/cxd56xx/common/src/cxd56_uid.c * * Copyright 2018 Sony Semiconductor Solutions Corporation * diff --git a/boards/arm/cxd56xx/spresense/src/cxd56_usbmsc.c b/boards/arm/cxd56xx/common/src/cxd56_usbmsc.c similarity index 98% rename from boards/arm/cxd56xx/spresense/src/cxd56_usbmsc.c rename to boards/arm/cxd56xx/common/src/cxd56_usbmsc.c index f8e62207c9..3ff56f109c 100644 --- a/boards/arm/cxd56xx/spresense/src/cxd56_usbmsc.c +++ b/boards/arm/cxd56xx/common/src/cxd56_usbmsc.c @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/arm/cxd56xx/spresense/src/cxd56_usbmsc.c + * boards/arm/cxd56xx/common/src/cxd56_usbmsc.c * * Copyright (C) 2009, 2011, 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/boards/arm/cxd56xx/spresense/src/Make.defs b/boards/arm/cxd56xx/spresense/src/Make.defs index f315448ac6..598deed337 100644 --- a/boards/arm/cxd56xx/spresense/src/Make.defs +++ b/boards/arm/cxd56xx/spresense/src/Make.defs @@ -33,7 +33,6 @@ ############################################################################ CSRCS += cxd56_main.c -CSRCS += cxd56_boot.c CSRCS += cxd56_clock.c CSRCS += cxd56_bringup.c @@ -46,10 +45,6 @@ ifeq ($(CONFIG_BOARDCTL_IOCTL),y) CSRCS += cxd56_ioctl.c endif -ifeq ($(CONFIG_BOARDCTL_UNIQUEID),y) -CSRCS += cxd56_uid.c -endif - ifeq ($(CONFIG_ARCH_FPU),y) CSRCS += cxd56_ostest.c endif @@ -74,10 +69,6 @@ ifeq ($(CONFIG_CXD56_PWM),y) CSRCS += cxd56_pwm.c endif -ifeq ($(CONFIG_CXD56_SFC),y) -CSRCS += cxd56_flash.c -endif - ifeq ($(CONFIG_SPI),y) CSRCS += cxd56_spi.c endif @@ -94,18 +85,10 @@ ifeq ($(CONFIG_CXD56_CHARGER),y) CSRCS += cxd56_charger.c endif -ifeq ($(CONFIG_USBMSC),y) -CSRCS += cxd56_usbmsc.c -endif - ifeq ($(CONFIG_USBDEV_COMPOSITE),y) CSRCS += cxd56_composite.c endif -ifeq ($(CONFIG_CXD56_I2C_DRIVER),y) -CSRCS += cxd56_i2cdev.c -endif - DEPPATH += --dep-path board VPATH += :board CFLAGS += $(shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)