mirror of
https://github.com/apache/nuttx.git
synced 2025-12-11 04:47:47 +08:00
bcm2711/sdio: Support for EMMC interfaces on the BCM2711
This initial implementation sets up support for the EMMC interfaces on the BCM2711. Only EMMC2 is tested since it is the interface of interest (connects to uSD card). MMCSD communication is functional and the boot partition of the SD card can be mounted and interacted with. Insertion/removal interrupts do not fire after initial boot, and sdstress fails with any byte size larger than 1023. 32GB card works perfectly, while 64GB card exhibits strange behaviour when interacting with VFAT filesystem. Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
This commit is contained in:
committed by
Alan C. Assis
parent
4e65e8a1f7
commit
d13b10843a
@@ -122,6 +122,7 @@ config ARCH_CHIP_BCM2711
|
||||
select ARCH_HAVE_MULTICPU
|
||||
select ARCH_USE_MMU # Required for up_testset
|
||||
select ARMV8A_HAVE_GICv2
|
||||
select ARCH_HAVE_SDIO
|
||||
---help---
|
||||
Broadcom BCM2711 quad-core ARM Cortex A72
|
||||
|
||||
|
||||
@@ -36,9 +36,15 @@ if(CONFIG_BCM2711_I2C)
|
||||
endif()
|
||||
|
||||
# SPI interfaces
|
||||
#
|
||||
|
||||
if(CONFIG_BCM2711_SPI)
|
||||
list(APPEND SRCS bcm2711_spi.c)
|
||||
endif()
|
||||
|
||||
# EMMC interfaces
|
||||
|
||||
if(CONFIG_BCM2711_EMMC)
|
||||
list(APPEND SRCS bcm2711_sdio.c)
|
||||
endif()
|
||||
|
||||
target_sources(arch PRIVATE ${SRCS})
|
||||
|
||||
@@ -281,6 +281,54 @@ config BCM2711_SPI6
|
||||
|
||||
endif # BCM2711_SPI
|
||||
|
||||
#####################################################################
|
||||
# SDMMC Configuration
|
||||
#####################################################################
|
||||
|
||||
config BCM2711_EMMC
|
||||
bool "EMMC support"
|
||||
select MMCSD
|
||||
select MMCSD_SDIO
|
||||
select SDIO_BLOCKSETUP
|
||||
depends on EXPERIMENTAL
|
||||
default n
|
||||
---help---
|
||||
Enables support for EMMC interfaces.
|
||||
|
||||
if BCM2711_EMMC
|
||||
|
||||
config BCM2711_EMMC1
|
||||
bool "EMMC1 interface support"
|
||||
depends on BCM2711_EMMC
|
||||
default n
|
||||
---help---
|
||||
Enables support for the EMMC1 interface.
|
||||
|
||||
config BCM2711_EMMC1_XFERSPEED
|
||||
int "EMMC1 transfer speed (Hz)"
|
||||
depends on BCM2711_EMMC1
|
||||
range 25000000 208000000
|
||||
default 25000000
|
||||
---help---
|
||||
The transfer speed in Hz to use for EMMC1 transfers.
|
||||
|
||||
config BCM2711_EMMC2
|
||||
bool "EMMC2 interface support"
|
||||
depends on BCM2711_EMMC
|
||||
default n
|
||||
---help---
|
||||
Enables support for the EMMC2 interface.
|
||||
|
||||
config BCM2711_EMMC2_XFERSPEED
|
||||
int "EMMC2 transfer speed (Hz)"
|
||||
depends on BCM2711_EMMC2
|
||||
range 25000000 208000000
|
||||
default 25000000
|
||||
---help---
|
||||
The transfer speed in Hz to use for EMMC2 transfers.
|
||||
|
||||
endif # BCM2711_EMMC
|
||||
|
||||
endmenu # Broadcom BCM2711 Peripheral Selection
|
||||
|
||||
endif # ARCH_CHIP_BCM2711
|
||||
|
||||
@@ -41,7 +41,13 @@ CHIP_CSRCS += bcm2711_i2c.c
|
||||
endif
|
||||
|
||||
# SPI interfaces
|
||||
#
|
||||
|
||||
ifeq ($(CONFIG_BCM2711_SPI),y)
|
||||
CHIP_CSRCS += bcm2711_spi.c
|
||||
endif
|
||||
|
||||
# EMMC interfaces
|
||||
|
||||
ifeq ($(CONFIG_BCM2711_EMMC),y)
|
||||
CHIP_CSRCS += bcm2711_sdio.c
|
||||
endif
|
||||
|
||||
@@ -107,7 +107,7 @@ struct bcm2711_mbox_tag_s
|
||||
|
||||
struct bcm2711_mbox_s
|
||||
{
|
||||
mutex_t lock; /* Lock for atomic request/response interactions */
|
||||
mutex_t lock; /* Lock for atomic request/response interactions */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -305,7 +305,7 @@ static int bcm2711_mbox_sendreq(FAR uint32_t *buf, uint8_t n)
|
||||
/* Unknown response code, typically due to unknown tag */
|
||||
|
||||
ipcerr("Unknown response code: %08x", buf[1]);
|
||||
return -EINVAL;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -328,7 +328,7 @@ static int bcm2711_mbox_sendreq(FAR uint32_t *buf, uint8_t n)
|
||||
****************************************************************************/
|
||||
|
||||
static void bcm2711_mbox_makereq(uint32_t tag, FAR void *buf, uint32_t nval,
|
||||
uint32_t nbuf)
|
||||
uint32_t nbuf)
|
||||
{
|
||||
void *bufpos = buf;
|
||||
struct bcm2711_mbox_tag_s mtag = {
|
||||
@@ -521,6 +521,47 @@ int bcm2711_mbox_getpwr(uint8_t id, bool *state)
|
||||
return err;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_setpwr
|
||||
*
|
||||
* Description:
|
||||
* Sets the power state of `id`.
|
||||
*
|
||||
* Input parameters:
|
||||
* id - The device ID to know the power state of
|
||||
* on - True for power on, false for power off
|
||||
* wait - True to block until power stable, false otherwise
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negated error code on failure.
|
||||
****************************************************************************/
|
||||
|
||||
int bcm2711_mbox_setpwr(uint8_t id, bool on, bool wait)
|
||||
{
|
||||
int err;
|
||||
uint32_t buf[BUF_FIELDS + TAG_FIELDS + 2] ALIGNED_MBOX;
|
||||
buf[0] = id; /* First argument is the device ID */
|
||||
|
||||
/* Second argument is power state. Bit 0 indicates desired state, bit 1
|
||||
* indicates desire to wait for stable power.
|
||||
*/
|
||||
|
||||
buf[1] = (on ? (1 << 0) : 0x0) | (wait ? (1 << 1) : 0x0);
|
||||
|
||||
bcm2711_mbox_makereq(MBOX_TAG_SETPWR, buf, 2 * sizeof(uint32_t),
|
||||
sizeof(buf));
|
||||
err = bcm2711_mbox_sendreq(buf, sizeof(buf));
|
||||
|
||||
/* Check if mailbox recognized device ID */
|
||||
|
||||
if (buf[6] & MBOX_DEVICE_DNE)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_ledset
|
||||
*
|
||||
@@ -548,3 +589,160 @@ int bcm2711_mbox_ledset(uint8_t pin, bool on)
|
||||
err = bcm2711_mbox_sendreq(buf, sizeof(buf));
|
||||
return err;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_getclken
|
||||
*
|
||||
* Description:
|
||||
* Get the state of the clock (enabled/disabled) corresponding to `id`
|
||||
*
|
||||
* Input parameters:
|
||||
* id - The ID of the clock to check
|
||||
* state - Where to store the state of the clock
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negated error code on failure.
|
||||
****************************************************************************/
|
||||
|
||||
int bcm2711_mbox_getclken(uint8_t id, bool *state)
|
||||
{
|
||||
int err;
|
||||
uint32_t buf[BUF_FIELDS + TAG_FIELDS + 2] ALIGNED_MBOX;
|
||||
|
||||
DEBUGASSERT(state != NULL);
|
||||
|
||||
buf[0] = id; /* Argument is clock ID */
|
||||
bcm2711_mbox_makereq(MBOX_TAG_GETCLKS, buf, 2 * sizeof(uint32_t),
|
||||
sizeof(buf));
|
||||
err = bcm2711_mbox_sendreq(buf, sizeof(buf));
|
||||
|
||||
/* Check if clock ID was recognized */
|
||||
|
||||
if (buf[6] & MBOX_DEVICE_DNE)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*state = buf[6] & 0x1;
|
||||
return err;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_setclken
|
||||
*
|
||||
* Description:
|
||||
* Set the state of the clock (enabled/disabled) corresponding to `id`
|
||||
*
|
||||
* Input parameters:
|
||||
* id - The ID of the clock
|
||||
* en - True to enable the clock, false otherwise
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negated error code on failure.
|
||||
****************************************************************************/
|
||||
|
||||
int bcm2711_mbox_setclken(uint8_t id, bool en)
|
||||
{
|
||||
int err;
|
||||
uint32_t buf[BUF_FIELDS + TAG_FIELDS + 2] ALIGNED_MBOX;
|
||||
buf[0] = id; /* First argument is clock ID */
|
||||
buf[1] = en ? 1 : 0; /* Second arg is clock state */
|
||||
|
||||
bcm2711_mbox_makereq(MBOX_TAG_SETCLKS, buf, 2 * sizeof(uint32_t),
|
||||
sizeof(buf));
|
||||
err = bcm2711_mbox_sendreq(buf, sizeof(buf));
|
||||
|
||||
/* Check if clock ID was recognized */
|
||||
|
||||
if (buf[6] & MBOX_DEVICE_DNE)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_getclkrate
|
||||
*
|
||||
* Description:
|
||||
* Get the rate of the clock corresponding to `id` in Hz.
|
||||
*
|
||||
* Input parameters:
|
||||
* id - The ID of the clock
|
||||
* rate - Where to store the rate of the clock
|
||||
* measured - True to return clock rate as a measured value (true rate),
|
||||
* false for configured rate.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negated error code on failure.
|
||||
****************************************************************************/
|
||||
|
||||
int bcm2711_mbox_getclkrate(uint8_t id, uint32_t *rate, bool measured)
|
||||
{
|
||||
int err;
|
||||
uint32_t buf[BUF_FIELDS + TAG_FIELDS + 2] ALIGNED_MBOX;
|
||||
buf[0] = id; /* Argument is clock ID */
|
||||
|
||||
DEBUGASSERT(rate != NULL);
|
||||
|
||||
bcm2711_mbox_makereq(measured ? MBOX_TAG_GETCLKRM : MBOX_TAG_GETCLKR, buf,
|
||||
2 * sizeof(uint32_t), sizeof(buf));
|
||||
err = bcm2711_mbox_sendreq(buf, sizeof(buf));
|
||||
|
||||
/* Returned clock rate is 0 when the clock does not exist (unless
|
||||
* measured). If the clock is not enabled, the return value for
|
||||
* unmeasured clock rate is the rate the clock will have when enabled.
|
||||
*/
|
||||
|
||||
if (buf[6] == 0 && !measured)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*rate = buf[6];
|
||||
return err;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_setclkrate
|
||||
*
|
||||
* Description:
|
||||
* Set the rate of the clock corresponding to `id` in Hz.
|
||||
*
|
||||
* Input parameters:
|
||||
* id - The ID of the clock
|
||||
* rate - The desired clock rate in Hz. The set rate will be returned in
|
||||
* this variable, even if the clock is not enabled
|
||||
* turbo - True to allow turbo settings (voltage, sdram and gpu), false
|
||||
* otherwise
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negated error code on failure.
|
||||
****************************************************************************/
|
||||
|
||||
int bcm2711_mbox_setclkrate(uint8_t id, uint32_t *rate, bool turbo)
|
||||
{
|
||||
int err;
|
||||
uint32_t buf[BUF_FIELDS + TAG_FIELDS + 3] ALIGNED_MBOX;
|
||||
|
||||
DEBUGASSERT(rate != NULL);
|
||||
|
||||
buf[0] = id; /* First arg is clock ID */
|
||||
buf[1] = *rate; /* Second arg is clock rate */
|
||||
buf[2] = turbo ? 0 : 1; /* Third arg is 1 to skip turbo */
|
||||
|
||||
bcm2711_mbox_makereq(MBOX_TAG_SETCLKR, buf, 3 * sizeof(uint32_t),
|
||||
sizeof(buf));
|
||||
err = bcm2711_mbox_sendreq(buf, sizeof(buf));
|
||||
|
||||
/* Returned clock rate is 0 when the clock does not exist. */
|
||||
|
||||
if (buf[6] == 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*rate = buf[6];
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -257,6 +257,23 @@ int bcm2711_mbox_getmac(uint64_t *mac);
|
||||
|
||||
int bcm2711_mbox_getpwr(uint8_t id, bool *state);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_setpwr
|
||||
*
|
||||
* Description:
|
||||
* Sets the power state of `id`.
|
||||
*
|
||||
* Input parameters:
|
||||
* id - The device ID to know the power state of
|
||||
* on - True for power on, false for power off
|
||||
* wait - True to block until power stable, false otherwise
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negated error code on failure.
|
||||
****************************************************************************/
|
||||
|
||||
int bcm2711_mbox_setpwr(uint8_t id, bool on, bool wait);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_ledset
|
||||
*
|
||||
@@ -273,6 +290,75 @@ int bcm2711_mbox_getpwr(uint8_t id, bool *state);
|
||||
|
||||
int bcm2711_mbox_ledset(uint8_t pin, bool on);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_getclken
|
||||
*
|
||||
* Description:
|
||||
* Get the state of the clock (enabled/disabled) corresponding to `id`
|
||||
*
|
||||
* Input parameters:
|
||||
* id - The ID of the clock to check
|
||||
* state - Where to store the state of the clock
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negated error code on failure.
|
||||
****************************************************************************/
|
||||
|
||||
int bcm2711_mbox_getclken(uint8_t id, bool *state);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_setclken
|
||||
*
|
||||
* Description:
|
||||
* Set the state of the clock (enabled/disabled) corresponding to `id`
|
||||
*
|
||||
* Input parameters:
|
||||
* id - The ID of the clock
|
||||
* en - True to enable the clock, false otherwise
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negated error code on failure.
|
||||
****************************************************************************/
|
||||
|
||||
int bcm2711_mbox_setclken(uint8_t id, bool en);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_getclkrate
|
||||
*
|
||||
* Description:
|
||||
* Get the rate of the clock corresponding to `id` in Hz.
|
||||
*
|
||||
* Input parameters:
|
||||
* id - The ID of the clock
|
||||
* rate - Where to store the rate of the clock
|
||||
* measured - True to return clock rate as a measured value (true rate),
|
||||
* false for configured rate.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negated error code on failure.
|
||||
****************************************************************************/
|
||||
|
||||
int bcm2711_mbox_getclkrate(uint8_t id, uint32_t *rate, bool measured);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_mbox_setclkrate
|
||||
*
|
||||
* Description:
|
||||
* Set the rate of the clock corresponding to `id` in Hz.
|
||||
*
|
||||
* Input parameters:
|
||||
* id - The ID of the clock
|
||||
* rate - The desired clock rate in Hz. The set rate will be returned in
|
||||
* this variable, even if the clock is not enabled
|
||||
* turbo - True to allow turbo settings (voltage, sdram and gpu), false
|
||||
* otherwise
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, negated error code on failure.
|
||||
****************************************************************************/
|
||||
|
||||
int bcm2711_mbox_setclkrate(uint8_t id, uint32_t *rate, bool turbo);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
2154
arch/arm64/src/bcm2711/bcm2711_sdio.c
Normal file
2154
arch/arm64/src/bcm2711/bcm2711_sdio.c
Normal file
File diff suppressed because it is too large
Load Diff
78
arch/arm64/src/bcm2711/bcm2711_sdio.h
Normal file
78
arch/arm64/src/bcm2711/bcm2711_sdio.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
* arch/arm64/src/bcm2711/bcm2711_sdio.h
|
||||
*
|
||||
* Author: Matteo Golin <matteo.golin@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM64_SRC_BCM2711_BCM2711_SDIO_H
|
||||
#define __ARCH_ARM64_SRC_BCM2711_BCM2711_SDIO_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "hardware/bcm2711_sdio.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm2711_sdio_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the BCM2711 SDIO peripheral for normal operation.
|
||||
*
|
||||
* Input Parameters:
|
||||
* slotno - 1 for EMMC1, 2 for EMMC2
|
||||
*
|
||||
* Returned Value:
|
||||
* A reference to an SDIO interface structure.
|
||||
* NULL is returned on failures.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct sdio_dev_s *bcm2711_sdio_initialize(int slotno);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ARCH_ARM64_SRC_BCM2711_BCM2711_SDIO_H */
|
||||
@@ -107,6 +107,12 @@
|
||||
|
||||
#define BCM_PACTL_CS (BCM_PERIPHERAL_BASEADDR + 0x204e00)
|
||||
|
||||
/* EMMC interface base addresses */
|
||||
|
||||
#define BCM_SDHOST_BASEADDR (BCM_PERIPHERAL_BASEADDR + 0x202000) /* SDHost */
|
||||
#define BCM_EMMC1_BASEADDR (BCM_PERIPHERAL_BASEADDR + 0x300000) /* EMMC1 */
|
||||
#define BCM_EMMC2_BASEADDR (BCM_PERIPHERAL_BASEADDR + 0x340000) /* EMMC2 */
|
||||
|
||||
/* ARM_LOCAL base address */
|
||||
|
||||
#if defined(CONFIG_BCM2711_LOW_PERIPHERAL)
|
||||
|
||||
312
arch/arm64/src/bcm2711/hardware/bcm2711_sdio.h
Normal file
312
arch/arm64/src/bcm2711/hardware/bcm2711_sdio.h
Normal file
@@ -0,0 +1,312 @@
|
||||
/****************************************************************************
|
||||
* arch/arm64/src/bcm2711/hardware/bcm2711_sdio.h
|
||||
*
|
||||
* Author: Matteo Golin <matteo.golin@gmail.com>
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM64_SRC_BCM2711_SDIO_H
|
||||
#define __ARCH_ARM64_SRC_BCM2711_SDIO_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "bcm2711_memmap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* SDIO (EMMC) register offsets, taken from BCM2835 datasheet */
|
||||
|
||||
#define BCM_SDIO_ARG2_OFFSET 0x0
|
||||
#define BCM_SDIO_BLKSIZECNT_OFFSET 0x4
|
||||
#define BCM_SDIO_ARG1_OFFSET 0x8
|
||||
#define BCM_SDIO_CMDTM_OFFSET 0xc
|
||||
#define BCM_SDIO_RESP0_OFFSET 0x10
|
||||
#define BCM_SDIO_RESP1_OFFSET 0x14
|
||||
#define BCM_SDIO_RESP2_OFFSET 0x18
|
||||
#define BCM_SDIO_RESP3_OFFSET 0x1c
|
||||
#define BCM_SDIO_DATA_OFFSET 0x20
|
||||
#define BCM_SDIO_STATUS_OFFSET 0x24
|
||||
#define BCM_SDIO_CONTROL0_OFFSET 0x28
|
||||
#define BCM_SDIO_CONTROL1_OFFSET 0x2c
|
||||
#define BCM_SDIO_INTERRUPT_OFFSET 0x30
|
||||
#define BCM_SDIO_IRPT_MASK_OFFSET 0x34
|
||||
#define BCM_SDIO_IRPT_EN_OFFSET 0x38
|
||||
#define BCM_SDIO_CONTROL2_OFFSET 0x3c
|
||||
#define BCM_SDIO_FORCE_IRPT_OFFSET 0x50
|
||||
#define BCM_SDIO_BOOT_TIMEOUT_OFFSET 0x70
|
||||
#define BCM_SDIO_DBG_SEL_OFFSET 0x74
|
||||
#define BCM_SDIO_EXRDFIFO_CFG_OFFSET 0x80
|
||||
#define BCM_SDIO_EXRDFIFO_EN_OFFSET 0x84
|
||||
#define BCM_SDIO_TUNE_STEP_OFFSET 0x88
|
||||
#define BCM_SDIO_TUNE_STEPS_STD_OFFSET 0x8c
|
||||
#define BCM_SDIO_TUNE_STEPS_DDR_OFFSET 0x90
|
||||
#define BCM_SDIO_SPI_INT_SPT_OFFSET 0xf0
|
||||
#define BCM_SDIO_SLOTISR_VER_OFFSET 0xfc
|
||||
|
||||
/* SDIO (EMMC) register addresses */
|
||||
|
||||
#define BCM_SDIO_ARG2(base) ((base) + BCM_SDIO_ARG2_OFFSET)
|
||||
#define BCM_SDIO_BLKSIZECNT(base) ((base) + BCM_SDIO_BLKSIZECNT_OFFSET)
|
||||
#define BCM_SDIO_ARG1(base) ((base) + BCM_SDIO_ARG1_OFFSET)
|
||||
#define BCM_SDIO_CMDTM(base) ((base) + BCM_SDIO_CMDTM_OFFSET)
|
||||
#define BCM_SDIO_RESP0(base) ((base) + BCM_SDIO_RESP0_OFFSET)
|
||||
#define BCM_SDIO_RESP1(base) ((base) + BCM_SDIO_RESP1_OFFSET)
|
||||
#define BCM_SDIO_RESP2(base) ((base) + BCM_SDIO_RESP2_OFFSET)
|
||||
#define BCM_SDIO_RESP3(base) ((base) + BCM_SDIO_RESP3_OFFSET)
|
||||
#define BCM_SDIO_DATA(base) ((base) + BCM_SDIO_DATA_OFFSET)
|
||||
#define BCM_SDIO_STATUS(base) ((base) + BCM_SDIO_STATUS_OFFSET)
|
||||
#define BCM_SDIO_CONTROL0(base) ((base) + BCM_SDIO_CONTROL0_OFFSET)
|
||||
#define BCM_SDIO_CONTROL1(base) ((base) + BCM_SDIO_CONTROL1_OFFSET)
|
||||
#define BCM_SDIO_INTERRUPT(base) ((base) + BCM_SDIO_INTERRUPT_OFFSET)
|
||||
#define BCM_SDIO_IRPT_MASK(base) ((base) + BCM_SDIO_IRPT_MASK_OFFSET)
|
||||
#define BCM_SDIO_IRPT_EN(base) ((base) + BCM_SDIO_IRPT_EN_OFFSET)
|
||||
#define BCM_SDIO_CONTROL2(base) ((base) + BCM_SDIO_CONTROL2_OFFSET)
|
||||
#define BCM_SDIO_FORCE_IRPT(base) ((base) + BCM_SDIO_FORCE_IRPT_OFFSET)
|
||||
#define BCM_SDIO_BOOT_TIMEOUT(base) ((base) + BCM_SDIO_BOOT_TIMEOUT_OFFSET)
|
||||
#define BCM_SDIO_DBG_SEL(base) ((base) + BCM_SDIO_DBG_SEL_OFFSET)
|
||||
#define BCM_SDIO_EXRDFIFO_CFG(base) ((base) + BCM_SDIO_EXRDFIFO_CFG_OFFSET)
|
||||
#define BCM_SDIO_EXRDFIFO_EN(base) ((base) + BCM_SDIO_EXRDFIFO_EN_OFFSET)
|
||||
#define BCM_SDIO_TUNE_STEP(base) ((base) + BCM_SDIO_TUNE_STEP_OFFSET)
|
||||
#define BCM_SDIO_TUNE_STEPS_STD(base) \
|
||||
((base) + BCM_SDIO_TUNE_STEPS_STD_OFFSET)
|
||||
#define BCM_SDIO_TUNE_STEPS_DDR(base) \
|
||||
((base) + BCM_SDIO_TUNE_STEPS_DDR_OFFSET)
|
||||
#define BCM_SDIO_SPI_INT_SPT(base) ((base) + BCM_SDIO_SPI_INT_SPT_OFFSET)
|
||||
#define BCM_SDIO_SLOTISR_VER(base) ((base) + BCM_SDIO_SLOTISR_VER_OFFSET)
|
||||
|
||||
/* SDIO (EMMC) register bit definitions.
|
||||
*
|
||||
* NOTE: some of these definitions are from the BCM2835 datasheet, while
|
||||
* others (which you won't find in the datasheet) are from the SD Host
|
||||
* Controller Simplified Specification.
|
||||
*/
|
||||
|
||||
#define BCM_SDIO_BLKSIZECNT_BLKSIZE_MASK (0x3ff)
|
||||
#define BCM_SDIO_BLKSIZECNT_BLKCNT_SHIFTLEN (16)
|
||||
#define BCM_SDIO_BLKSIZECNT_BLKCNT_MASK (0xffff)
|
||||
|
||||
#define BCM_SDIO_CMDTM_TM_BLKCNT_EN (1 << 1)
|
||||
#define BCM_SDIO_CMDTM_TM_AUTO_CMD_EN (0x3 << 2)
|
||||
#define BCM_SDIO_CMDTM_TM_DAT_DIR (1 << 4)
|
||||
#define BCM_SDIO_CMDTM_TM_MULTI_BLOCK (1 << 5)
|
||||
|
||||
#define BCM_SDIO_CMDTM_CMD_RSPNS_TYPE (0x3 << 16)
|
||||
#define BCM_SDIO_CMDTM_CMD_RSPNS_TYPE_NONE (0x0 << 16) /* No response */
|
||||
#define BCM_SDIO_CMDTM_CMD_RSPNS_TYPE_136 (0x1 << 16) /* 136 bits */
|
||||
#define BCM_SDIO_CMDTM_CMD_RSPNS_TYPE_48 (0x2 << 16) /* 48 bits */
|
||||
#define BCM_SDIO_CMDTM_CMD_RSPNS_TYPE_48B (0x3 << 16) /* 48 bits busy */
|
||||
|
||||
#define BCM_SDIO_CMDTM_CMD_CRCCHK_EN (1 << 19)
|
||||
#define BCM_SDIO_CMDTM_CMD_IXCHK_EN (1 << 20)
|
||||
#define BCM_SDIO_CMDTM_CMD_ISDATA (1 << 21)
|
||||
#define BCM_SDIO_CMDTM_CMD_TYPE (0x3 << 22)
|
||||
#define BCM_SDIO_CMDTM_CMD_INDEX_SHIFT (24)
|
||||
#define BCM_SDIO_CMDTM_CMD_INDEX (0x3f << BCM_SDIO_CMDTM_CMD_INDEX_SHIFT)
|
||||
|
||||
#define BCM_SDIO_STATUS_CMD_INHIBIT (1 << 0)
|
||||
#define BCM_SDIO_STATUS_DAT_INHIBIT (1 << 1)
|
||||
#define BCM_SDIO_STATUS_DAT_ACTIVE (1 << 2)
|
||||
#define BCM_SDIO_STATUS_WRITE_TRANSFER (1 << 8)
|
||||
#define BCM_SDIO_STATUS_READ_TRANSFER (1 << 9)
|
||||
#define BCM_SDIO_STATUS_CARD_INSERTED (1 << 16)
|
||||
#define BCM_SDIO_STATUS_CARDDET_STABLE (1 << 17)
|
||||
#define BCM_SDIO_STATUS_CARDDET_LEVEL (1 << 18)
|
||||
#define BCM_SDIO_STATUS_WRPROT_LEVEL (1 << 19)
|
||||
#define BCM_SDIO_STATUS_DAT_LEVEL0 (0xf << 20)
|
||||
#define BCM_SDIO_STATUS_CMD_LEVEL (1 << 24)
|
||||
#define BCM_SDIO_STATUS_DAT_LEVEL1 (0xf << 25)
|
||||
|
||||
#define BCM_SDIO_CONTROL0_HCTL_DWIDTH (1 << 1)
|
||||
#define BCM_SDIO_CONTROL0_HCTL_HS_EN (1 << 2)
|
||||
#define BCM_SDIO_CONTROL0_HCTL_8BIT (1 << 5)
|
||||
#define BCM_SDIO_CONTROL0_VDD1_ON (1 << 8)
|
||||
#define BCM_SDIO_CONTROL0_VDD1_SHIFT (9)
|
||||
#define BCM_SDIO_CONTROL0_VDD1_MASK (0x7)
|
||||
#define BCM_SDIO_CONTROL0_VDD1_3V3 (0x7 << BCM_SDIO_CONTROL0_VDD1_SHIFT)
|
||||
#define BCM_SDIO_CONTROL0_VDD1_3V (0x6 << BCM_SDIO_CONTROL0_VDD1_SHIFT)
|
||||
#define BCM_SDIO_CONTROL0_VDD1_1V8 (0x5 << BCM_SDIO_CONTROL0_VDD1_SHIFT)
|
||||
#define BCM_SDIO_CONTROL0_GAP_STOP (1 << 16)
|
||||
#define BCM_SDIO_CONTROL0_GAP_RESTART (1 << 17)
|
||||
#define BCM_SDIO_CONTROL0_READWAIT_EN (1 << 18)
|
||||
#define BCM_SDIO_CONTROL0_GAP_IEN (1 << 19)
|
||||
#define BCM_SDIO_CONTROL0_SPI_MODE (1 << 20)
|
||||
#define BCM_SDIO_CONTROL0_BOOT_EN (1 << 21)
|
||||
#define BCM_SDIO_CONTROL0_ALT_BOOT_EN (1 << 22)
|
||||
#define BCM_SDIO_CONTROL0_WKUP_INSERT (1 << 25)
|
||||
#define BCM_SDIO_CONTROL0_WKUP_REMOVAL (1 << 26)
|
||||
|
||||
#define BCM_SDIO_CONTROL1_CLK_INTLEN (1 << 0)
|
||||
#define BCM_SDIO_CONTROL1_CLK_STABLE (1 << 1)
|
||||
#define BCM_SDIO_CONTROL1_CLK_EN (1 << 2)
|
||||
#define BCM_SDIO_CONTROL1_CLK_GENSEL (1 << 5)
|
||||
#define BCM_SDIO_CONTROL1_CLK_FREQ_MS2 (0x3 << 6)
|
||||
#define BCM_SDIO_CONTROL1_CLK_FREQ8 (0xff << 8)
|
||||
#define BCM_SDIO_CONTROL1_DATA_TOUNIT_MASK (0xf)
|
||||
#define BCM_SDIO_CONTROL1_DATA_TOUNIT_SHIFT (16)
|
||||
#define BCM_SDIO_CONTROL1_DATA_TOUNIT \
|
||||
(BCM_SDIO_CONTROL1_DATA_TOUNIT_MASK << BCM_SDIO_CONTROL1_DATA_TOUNIT_SHIFT)
|
||||
#define BCM_SDIO_CONTROL1_SRST_HC (1 << 24)
|
||||
#define BCM_SDIO_CONTROL1_SRST_CMD (1 << 25)
|
||||
#define BCM_SDIO_CONTROL1_SRST_DATA (1 << 26)
|
||||
|
||||
#define BCM_SDIO_INTERRUPT_CMD_DONE (1 << 0)
|
||||
#define BCM_SDIO_INTERRUPT_DATA_DONE (1 << 1)
|
||||
#define BCM_SDIO_INTERRUPT_BLOCK_GAP (1 << 2)
|
||||
#define BCM_SDIO_INTERRUPT_WRITE_RDY (1 << 4)
|
||||
#define BCM_SDIO_INTERRUPT_READ_RDY (1 << 5)
|
||||
#define BCM_SDIO_INTERRUPT_INSERTION (1 << 6)
|
||||
#define BCM_SDIO_INTERRUPT_REMOVAL (1 << 7)
|
||||
#define BCM_SDIO_INTERRUPT_CARD (1 << 8)
|
||||
#define BCM_SDIO_INTERRUPT_RETUNE (1 << 12)
|
||||
#define BCM_SDIO_INTERRUPT_BOOTACK (1 << 13)
|
||||
#define BCM_SDIO_INTERRUPT_ENDBOOT (1 << 14)
|
||||
#define BCM_SDIO_INTERRUPT_ERR (1 << 15)
|
||||
#define BCM_SDIO_INTERRUPT_CTO_ERR (1 << 16)
|
||||
#define BCM_SDIO_INTERRUPT_CCRC_ERR (1 << 17)
|
||||
#define BCM_SDIO_INTERRUPT_CEND_ERR (1 << 18)
|
||||
#define BCM_SDIO_INTERRUPT_CBAD_ERR (1 << 19)
|
||||
#define BCM_SDIO_INTERRUPT_DTO_ERR (1 << 20)
|
||||
#define BCM_SDIO_INTERRUPT_DCRC_ERR (1 << 21)
|
||||
#define BCM_SDIO_INTERRUPT_DEND_ERR (1 << 22)
|
||||
#define BCM_SDIO_INTERRUPT_ACMD_ERR (1 << 24)
|
||||
#define BCM_SDIO_INTERRUPT_ALL \
|
||||
(BCM_SDIO_INTERRUPT_CMD_DONE | BCM_SDIO_INTERRUPT_DATA_DONE | \
|
||||
BCM_SDIO_INTERRUPT_BLOCK_GAP | BCM_SDIO_INTERRUPT_WRITE_RDY | \
|
||||
BCM_SDIO_INTERRUPT_READ_RDY | BCM_SDIO_INTERRUPT_INSERTION | \
|
||||
BCM_SDIO_INTERRUPT_REMOVAL | BCM_SDIO_INTERRUPT_CARD | \
|
||||
BCM_SDIO_INTERRUPT_RETUNE | BCM_SDIO_INTERRUPT_BOOTACK | \
|
||||
BCM_SDIO_INTERRUPT_ENDBOOT | BCM_SDIO_INTERRUPT_CTO_ERR | \
|
||||
BCM_SDIO_INTERRUPT_CCRC_ERR | BCM_SDIO_INTERRUPT_CEND_ERR | \
|
||||
BCM_SDIO_INTERRUPT_CBAD_ERR | BCM_SDIO_INTERRUPT_DTO_ERR | \
|
||||
BCM_SDIO_INTERRUPT_DCRC_ERR | BCM_SDIO_INTERRUPT_DEND_ERR | \
|
||||
BCM_SDIO_INTERRUPT_ACMD_ERR)
|
||||
|
||||
#define BCM_SDIO_IRPT_MASK_CMD_DONE (1 << 0)
|
||||
#define BCM_SDIO_IRPT_MASK_DATA_DONE (1 << 1)
|
||||
#define BCM_SDIO_IRPT_MASK_BLOCK_GAP (1 << 2)
|
||||
#define BCM_SDIO_IRPT_MASK_WRITE_RDY (1 << 4)
|
||||
#define BCM_SDIO_IRPT_MASK_READ_RDY (1 << 5)
|
||||
#define BCM_SDIO_IRPT_MASK_INSERTION (1 << 6)
|
||||
#define BCM_SDIO_IRPT_MASK_REMOVAL (1 << 7)
|
||||
#define BCM_SDIO_IRPT_MASK_CARD (1 << 8)
|
||||
#define BCM_SDIO_IRPT_MASK_RETUNE (1 << 12)
|
||||
#define BCM_SDIO_IRPT_MASK_BOOTACK (1 << 13)
|
||||
#define BCM_SDIO_IRPT_MASK_ENDBOOT (1 << 14)
|
||||
#define BCM_SDIO_IRPT_MASK_CTO_ERR (1 << 16)
|
||||
#define BCM_SDIO_IRPT_MASK_CCRC_ERR (1 << 17)
|
||||
#define BCM_SDIO_IRPT_MASK_CEND_ERR (1 << 18)
|
||||
#define BCM_SDIO_IRPT_MASK_CBAD_ERR (1 << 19)
|
||||
#define BCM_SDIO_IRPT_MASK_DTO_ERR (1 << 20)
|
||||
#define BCM_SDIO_IRPT_MASK_DCRC_ERR (1 << 21)
|
||||
#define BCM_SDIO_IRPT_MASK_DEND_ERR (1 << 22)
|
||||
#define BCM_SDIO_IRPT_MASK_ACMD_ERR (1 << 24)
|
||||
#define BCM_SDIO_IRPT_MASK_ALL \
|
||||
(BCM_SDIO_IRPT_MASK_CMD_DONE | BCM_SDIO_IRPT_MASK_DATA_DONE | \
|
||||
BCM_SDIO_IRPT_MASK_BLOCK_GAP | BCM_SDIO_IRPT_MASK_WRITE_RDY | \
|
||||
BCM_SDIO_IRPT_MASK_READ_RDY | BCM_SDIO_IRPT_MASK_INSERTION | \
|
||||
BCM_SDIO_IRPT_MASK_REMOVAL | BCM_SDIO_IRPT_MASK_CARD | \
|
||||
BCM_SDIO_IRPT_MASK_RETUNE | BCM_SDIO_IRPT_MASK_BOOTACK | \
|
||||
BCM_SDIO_IRPT_MASK_ENDBOOT | BCM_SDIO_IRPT_MASK_CTO_ERR | \
|
||||
BCM_SDIO_IRPT_MASK_CCRC_ERR | BCM_SDIO_IRPT_MASK_CEND_ERR | \
|
||||
BCM_SDIO_IRPT_MASK_CBAD_ERR | BCM_SDIO_IRPT_MASK_DTO_ERR | \
|
||||
BCM_SDIO_IRPT_MASK_DCRC_ERR | BCM_SDIO_IRPT_MASK_DEND_ERR | \
|
||||
BCM_SDIO_IRPT_MASK_ACMD_ERR)
|
||||
|
||||
#define BCM_SDIO_IRPT_EN_CMD_DONE (1 << 0)
|
||||
#define BCM_SDIO_IRPT_EN_DATA_DONE (1 << 1)
|
||||
#define BCM_SDIO_IRPT_EN_BLOCK_GAP (1 << 2)
|
||||
#define BCM_SDIO_IRPT_EN_WRITE_RDY (1 << 4)
|
||||
#define BCM_SDIO_IRPT_EN_READ_RDY (1 << 5)
|
||||
#define BCM_SDIO_IRPT_EN_INSERTION (1 << 6)
|
||||
#define BCM_SDIO_IRPT_EN_REMOVAL (1 << 7)
|
||||
#define BCM_SDIO_IRPT_EN_CARD (1 << 8)
|
||||
#define BCM_SDIO_IRPT_EN_RETUNE (1 << 12)
|
||||
#define BCM_SDIO_IRPT_EN_BOOTACK (1 << 13)
|
||||
#define BCM_SDIO_IRPT_EN_ENDBOOT (1 << 14)
|
||||
#define BCM_SDIO_IRPT_EN_CTO_ERR (1 << 16)
|
||||
#define BCM_SDIO_IRPT_EN_CCRC_ERR (1 << 17)
|
||||
#define BCM_SDIO_IRPT_EN_CEND_ERR (1 << 18)
|
||||
#define BCM_SDIO_IRPT_EN_CBAD_ERR (1 << 19)
|
||||
#define BCM_SDIO_IRPT_EN_DTO_ERR (1 << 20)
|
||||
#define BCM_SDIO_IRPT_EN_DCRC_ERR (1 << 21)
|
||||
#define BCM_SDIO_IRPT_EN_DEND_ERR (1 << 22)
|
||||
#define BCM_SDIO_IRPT_EN_ACMD_ERR (1 << 24)
|
||||
#define BCM_SDIO_IRPT_EN_ALL \
|
||||
(BCM_SDIO_IRPT_EN_CMD_DONE | BCM_SDIO_IRPT_EN_DATA_DONE | \
|
||||
BCM_SDIO_IRPT_EN_BLOCK_GAP | BCM_SDIO_IRPT_EN_WRITE_RDY | \
|
||||
BCM_SDIO_IRPT_EN_READ_RDY | BCM_SDIO_IRPT_EN_INSERTION | \
|
||||
BCM_SDIO_IRPT_EN_REMOVAL | BCM_SDIO_IRPT_EN_CARD | \
|
||||
BCM_SDIO_IRPT_EN_RETUNE | BCM_SDIO_IRPT_EN_BOOTACK | \
|
||||
BCM_SDIO_IRPT_EN_ENDBOOT | BCM_SDIO_IRPT_EN_CTO_ERR | \
|
||||
BCM_SDIO_IRPT_EN_CCRC_ERR | BCM_SDIO_IRPT_EN_CEND_ERR | \
|
||||
BCM_SDIO_IRPT_EN_CBAD_ERR | BCM_SDIO_IRPT_EN_DTO_ERR | \
|
||||
BCM_SDIO_IRPT_EN_DCRC_ERR | BCM_SDIO_IRPT_EN_DEND_ERR | \
|
||||
BCM_SDIO_IRPT_EN_ACMD_ERR)
|
||||
|
||||
#define BCM_SDIO_CONTROL2_ACNOX_ERR (1 << 0)
|
||||
#define BCM_SDIO_CONTROL2_ACTO_ERR (1 << 1)
|
||||
#define BCM_SDIO_CONTROL2_ACCRC_ERR (1 << 2)
|
||||
#define BCM_SDIO_CONTROL2_ACEND_ERR (1 << 3)
|
||||
#define BCM_SDIO_CONTROL2_ACBAD_ERR (1 << 4)
|
||||
#define BCM_SDIO_CONTROL2_NOTC12_ERR (1 << 7)
|
||||
#define BCM_SDIO_CONTROL2_UHSMODE (0x7 << 16)
|
||||
#define BCM_SDIO_CONTROL2_TUNEON (1 << 22)
|
||||
#define BCM_SDIO_CONTROL2_TUNED (1 << 23)
|
||||
|
||||
#define BCM_SDIO_FORCE_IRPT_CMD_DONE (1 << 0)
|
||||
#define BCM_SDIO_FORCE_IRPT_DATA_DONE (1 << 1)
|
||||
#define BCM_SDIO_FORCE_IRPT_BLOCK_GAP (1 << 2)
|
||||
#define BCM_SDIO_FORCE_IRPT_WRITE_RDY (1 << 4)
|
||||
#define BCM_SDIO_FORCE_IRPT_READ_RDY (1 << 5)
|
||||
#define BCM_SDIO_FORCE_IRPT_CARD (1 << 8)
|
||||
#define BCM_SDIO_FORCE_IRPT_RETUNE (1 << 12)
|
||||
#define BCM_SDIO_FORCE_IRPT_BOOTACK (1 << 13)
|
||||
#define BCM_SDIO_FORCE_IRPT_ENDBOOT (1 << 14)
|
||||
#define BCM_SDIO_FORCE_IRPT_CTO_ERR (1 << 16)
|
||||
#define BCM_SDIO_FORCE_IRPT_CCRC_ERR (1 << 17)
|
||||
#define BCM_SDIO_FORCE_IRPT_CEND_ERR (1 << 18)
|
||||
#define BCM_SDIO_FORCE_IRPT_CBAD_ERR (1 << 19)
|
||||
#define BCM_SDIO_FORCE_IRPT_DTO_ERR (1 << 20)
|
||||
#define BCM_SDIO_FORCE_IRPT_DCRC_ERR (1 << 21)
|
||||
#define BCM_SDIO_FORCE_IRPT_DEND_ERR (1 << 22)
|
||||
#define BCM_SDIO_FORCE_IRPT_ACMD_ERR (1 << 24)
|
||||
#define BCM_SDIO_FORCE_IRPT_ALL (0x17ff137)
|
||||
|
||||
#define BCM_SDIO_DBG_SEL_SELECT (1 << 0)
|
||||
|
||||
#define BCM_SDIO_EXRDFIFO_CFG_RD_THRSH (0x7 << 0)
|
||||
|
||||
#define BCM_SDIO_EXRDFIFO_EN_ENABLE (1 << 0)
|
||||
|
||||
#define BCM_SDIO_TUNE_STEP_DELAY (0x7 << 0)
|
||||
|
||||
#define BCM_SDIO_TUNE_STEPS_STD_STEPS (0x3f << 0)
|
||||
|
||||
#define BCM_SDIO_TUNE_STEPS_DDR_STEPS (0x3f << 0)
|
||||
|
||||
#define BCM_SDIO_SPI_INT_SPT_SELECT (0xff << 0)
|
||||
|
||||
#define BCM_SDIO_SLOTISR_VER_SLOT_STATUS (0xff << 0)
|
||||
#define BCM_SDIO_SLOTISR_VER_SDVERSION (0xff << 16)
|
||||
#define BCM_SDIO_SLOTISR_VER_VENDOR (0xff << 24)
|
||||
|
||||
#endif /* __ARCH_ARM64_SRC_BCM2711_SDIO_H */
|
||||
@@ -37,4 +37,20 @@ config RPI4B_DEBUG_BOOT
|
||||
---help---
|
||||
Enables the debug output of the Raspberry Pi 4B bootloader.
|
||||
|
||||
config RPI4B_SDMMC
|
||||
bool "Mount uSD as MMCSD device"
|
||||
depends on BCM2711_EMMC2
|
||||
default n
|
||||
---help---
|
||||
Mounts the uSD card as an MMCSD device.
|
||||
|
||||
config RPI4B_MOUNT_BOOT
|
||||
bool "Mount boot partition"
|
||||
depends on RPI4B_SDMMC
|
||||
depends on FS_FAT
|
||||
default n
|
||||
---help---
|
||||
Mounts the boot partition of the micro SD card to NuttX as a read/write
|
||||
file system.
|
||||
|
||||
endif # ARCH_BOARD_RASPBERRYPI_4B
|
||||
|
||||
79
boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig
Normal file
79
boards/arm64/bcm2711/raspberrypi-4b/configs/sd/defconfig
Normal file
@@ -0,0 +1,79 @@
|
||||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
CONFIG_ALLOW_BSD_COMPONENTS=y
|
||||
CONFIG_ARCH="arm64"
|
||||
CONFIG_ARCH_ARM64=y
|
||||
CONFIG_ARCH_BOARD="raspberrypi-4b"
|
||||
CONFIG_ARCH_BOARD_RASPBERRYPI_4B=y
|
||||
CONFIG_ARCH_CHIP="bcm2711"
|
||||
CONFIG_ARCH_CHIP_BCM2711=y
|
||||
CONFIG_ARCH_EARLY_PRINT=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=4096
|
||||
CONFIG_BCM2711_EMMC2=y
|
||||
CONFIG_BCM2711_EMMC=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=132954
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_ASSERTIONS=y
|
||||
CONFIG_DEBUG_ASSERTIONS_EXPRESSION=y
|
||||
CONFIG_DEBUG_FEATURES=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_DEBUG_FS_ERROR=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_IPC=y
|
||||
CONFIG_DEBUG_IPC_ERROR=y
|
||||
CONFIG_DEBUG_IPC_WARN=y
|
||||
CONFIG_DEBUG_MEMCARD=y
|
||||
CONFIG_DEBUG_MEMCARD_ERROR=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEFAULT_TASK_STACKSIZE=8192
|
||||
CONFIG_EXPERIMENTAL=y
|
||||
CONFIG_FAT_LCNAMES=y
|
||||
CONFIG_FAT_LFN=y
|
||||
CONFIG_FS_FAT=y
|
||||
CONFIG_FS_FATTIME=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_ROMFS=y
|
||||
CONFIG_HAVE_CXX=y
|
||||
CONFIG_HAVE_CXXINITIALIZE=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=8192
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_FILEIOSIZE=512
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_PTHREAD_STACK_MIN=8192
|
||||
CONFIG_RAMLOG=y
|
||||
CONFIG_RAM_SIZE=4227858432
|
||||
CONFIG_RAM_START=0x00000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_READLINE_CMD_HISTORY=y
|
||||
CONFIG_RPI4B_MOUNT_BOOT=y
|
||||
CONFIG_RPI4B_SDMMC=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SPINLOCK=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_MONTH=11
|
||||
CONFIG_START_YEAR=2022
|
||||
CONFIG_SYMTAB_ORDEREDBYNAME=y
|
||||
CONFIG_SYSLOG_BUFFER=y
|
||||
CONFIG_SYSLOG_BUFSIZE=128
|
||||
CONFIG_SYSLOG_INTBUFFER=y
|
||||
CONFIG_SYSLOG_TIMESTAMP=y
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_SYSTEM_SYSTEM=y
|
||||
CONFIG_SYSTEM_TIME64=y
|
||||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_TESTING_SD_STRESS=y
|
||||
CONFIG_TESTING_SD_STRESS_DEVICE="/sd"
|
||||
CONFIG_USEC_PER_TICK=1000
|
||||
CONFIG_USERLED=y
|
||||
@@ -55,4 +55,8 @@
|
||||
#define BOARD_NGPIOIN 1
|
||||
#define BOARD_NGPIOINT 0
|
||||
|
||||
/* Micro SD card slot number to use */
|
||||
|
||||
#define MICROSD_SLOTNO 0
|
||||
|
||||
#endif /* __BOARDS_ARM64_BCM2711_RPI4B_INCLUDE_BOARD_H */
|
||||
|
||||
@@ -32,6 +32,10 @@ if(CONFIG_DEV_GPIO)
|
||||
list(APPEND SRCS rpi4b_gpio.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_RPI4B_SDMMC)
|
||||
list(APPEND rpi4b_sdmmc.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BCM2711_I2C_DRIVER)
|
||||
list(APPEND SRCS bcm2711_i2cdev.c)
|
||||
endif()
|
||||
|
||||
@@ -34,6 +34,10 @@ ifeq ($(CONFIG_DEV_GPIO),y)
|
||||
CSRCS += rpi4b_gpio.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RPI4B_SDMMC),y)
|
||||
CSRCS += rpi4b_sdmmc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BCM2711_I2C_DRIVER),y)
|
||||
CSRCS += bcm2711_i2cdev.c
|
||||
endif
|
||||
|
||||
@@ -45,6 +45,18 @@
|
||||
int rpi4b_bringup(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rpi4b_sdmmc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize uSD card on EMMC2 as an MMCSD device.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_RPI4B_SDMMC)
|
||||
int rpi4b_sdmmc_initialize(void);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DEV_GPIO)
|
||||
int bcm2711_dev_gpio_init(void);
|
||||
#endif /* defined(CONFIG_DEV_GPIO) */
|
||||
|
||||
@@ -24,14 +24,16 @@
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "rpi4b.h"
|
||||
#include <debug.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef CONFIG_BOARDCTL
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include "rpi4b.h"
|
||||
#include <arch/board/board.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -73,7 +75,7 @@ int board_app_initialize(uintptr_t arg)
|
||||
ret = nx_mount(NULL, "/proc", "procfs", 0, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("ERROR: Failed to mount procfs at /proc: %d\n", ret);
|
||||
syslog(LOG_ERR, "ERROR: Failed to mount procfs at /proc: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -83,7 +85,17 @@ int board_app_initialize(uintptr_t arg)
|
||||
ret = rpi4b_bringup();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RPI4B_MOUNT_BOOT
|
||||
/* Mount SD card file system (currently just the boot (first) partition).
|
||||
* Assumes /dev/mmcsd0 exists, but if it doesn't it will fail gracefully.
|
||||
*/
|
||||
|
||||
ret = nx_mount("/dev/mmcsd0", "/sd", "vfat", 0, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Could not mount SD card FAT partition: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOARDCTL */
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
@@ -36,7 +37,9 @@
|
||||
#include "bcm2711_i2c.h"
|
||||
#endif
|
||||
|
||||
#include "bcm2711_mailbox.h"
|
||||
#ifdef CONFIG_RPI4B_MOUNT_BOOT
|
||||
#include <nuttx/fs/fs.h>
|
||||
#endif
|
||||
|
||||
#include "rpi4b.h"
|
||||
|
||||
@@ -128,5 +131,15 @@ int rpi4b_bringup(void)
|
||||
|
||||
#endif /* defined(CONFIG_BCM2711_I2C) */
|
||||
|
||||
#ifdef CONFIG_RPI4B_SDMMC
|
||||
/* Mount SD card file system */
|
||||
|
||||
ret = rpi4b_sdmmc_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Couldn't initialize SDMMC: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
72
boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_sdmmc.c
Normal file
72
boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_sdmmc.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
* boards/arm64/bcm2711/raspberrypi-4b/src/rpi4b_sdmmc.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/mmcsd.h>
|
||||
|
||||
#include "bcm2711_sdio.h"
|
||||
|
||||
#include "rpi4b.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rpi4b_sdmmc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Bring up EMMC2 interface and mount micro-SD card as a file system.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int rpi4b_sdmmc_initialize(void)
|
||||
{
|
||||
int err;
|
||||
struct sdio_dev_s *emmc2;
|
||||
|
||||
/* Initialize EMMC2 interface */
|
||||
|
||||
emmc2 = bcm2711_sdio_initialize(2);
|
||||
if (emmc2 == NULL)
|
||||
{
|
||||
syslog(LOG_ERR, "Couldn't initialize EMMC2");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Set up MMCSD device (uSD) on EMMC2 */
|
||||
|
||||
err = mmcsd_slotinitialize(0, emmc2);
|
||||
if (err < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Couldn't bind EMMC2 interface to MMC/SD driver: %d",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
Reference in New Issue
Block a user