Difference between revisions of "Unit BCMSDHOST"

From Ultibo.org
Jump to: navigation, search
 
(5 intermediate revisions by the same user not shown)
Line 5: Line 5:
 
----
 
----
  
'''Broadcom BCM27XX SDHOST driver'''
+
'''Broadcom BCM27XX SDHOST Driver unit'''
  
 
The SDHOST controller on the BCM27XX is a non SDHCI-compliant device which requires a specific driver.
 
The SDHOST controller on the BCM27XX is a non SDHCI-compliant device which requires a specific driver.
Line 16: Line 16:
 
----
 
----
  
''To be documented''
+
 
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''BCMSDHOST specific constants''' <code> BCMSDHOST_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>BCMSDHOST_DESCRIPTION = 'Broadcom BCM27XX SDHOST';</code>
 +
| style="width: 50%;"|Description of BCMSDHOST device
 +
|-
 +
|colspan="2"|&nbsp;
 +
|-
 +
| <code>BCMSDHOST_FIFO_READ_THRESHOLD = 4;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_FIFO_WRITE_THRESHOLD = 4;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_ALLOW_CMD23_READ = 1;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_ALLOW_CMD23_WRITE = 0;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDDATA_FIFO_PIO_BURST = 8;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_CMD_DALLY_US = 1;</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''BCMSDHOST register''' <code> BCMSDHOST_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>BCMSDHOST_SDCMD = $00;</code>
 +
| style="width: 50%;"|Command to SD card - 16 R/W
 +
|-
 +
| <code>BCMSDHOST_SDARG = $04;</code>
 +
| Argument to SD card - 32 R/W
 +
|-
 +
| <code>BCMSDHOST_SDTOUT = $08;</code>
 +
| Start value for timeout counter - 32 R/W
 +
|-
 +
| <code>BCMSDHOST_SDCDIV = $0c;</code>
 +
| Start value for clock divider - 11 R/W
 +
|-
 +
| <code>BCMSDHOST_SDRSP0 = $10;</code>
 +
| SD card response (31:0)- 32 R
 +
|-
 +
| <code>BCMSDHOST_SDRSP1 = $14;</code>
 +
| SD card response (63:32) - 32 R
 +
|-
 +
| <code>BCMSDHOST_SDRSP2 = $18;</code>
 +
| SD card response (95:64) - 32 R
 +
|-
 +
| <code>BCMSDHOST_SDRSP3 = $1c;</code>
 +
| SD card response (127:96)- 32 R
 +
|-
 +
| <code>BCMSDHOST_SDHSTS = $20;</code>
 +
| SD host status - 11 R
 +
|-
 +
| <code>BCMSDHOST_SDVDD = $30;</code>
 +
| SD card power control - 1 R/W
 +
|-
 +
| <code>BCMSDHOST_SDEDM = $34;</code>
 +
| Emergency Debug Mode - 13 R/W
 +
|-
 +
| <code>BCMSDHOST_SDHCFG = $38;</code>
 +
| Host configuration - 2 R/W
 +
|-
 +
| <code>BCMSDHOST_SDHBCT = $3c;</code>
 +
| Host byte count (debug) - 32 R/W
 +
|-
 +
| <code>BCMSDHOST_SDDATA = $40;</code>
 +
| Data to/from SD card - 32 R/W
 +
|-
 +
| <code>BCMSDHOST_SDHBLC = $50;</code>
 +
| Host block count (SDIO/SDHC) - 9 R/W
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''BCMSDHOST command register''' <code> BCMSDHOST_SDCMD_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>BCMSDHOST_SDCMD_NEW_FLAG = $8000;</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDCMD_FAIL_FLAG = $4000;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDCMD_BUSYWAIT = $800;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDCMD_NO_RESPONSE = $400;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDCMD_LONG_RESPONSE = $200;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDCMD_WRITE_CMD = $80;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDCMD_READ_CMD = $40;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDCMD_CMD_MASK = $3f;</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''BCMSDHOST clock divider register''' <code> BCMSDHOST_SDCDIV_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>BCMSDHOST_SDCDIV_MAX_CDIV = $7ff;</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''BCMSDHOST host status register''' <code> BCMSDHOST_SDHSTS_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_BUSY_IRPT = $400;</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_BLOCK_IRPT = $200;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_SDIO_IRPT = $100;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_REW_TIME_OUT = $80;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_CMD_TIME_OUT = $40;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_CRC16_ERROR = $20;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_CRC7_ERROR = $10;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_FIFO_ERROR = $08;</code>
 +
| &nbsp;
 +
|-
 +
|colspan="2"|04 Reserved
 +
|-
 +
|colspan="2"|02 Reserved
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_DATA_FLAG = $01;</code>
 +
| &nbsp;
 +
|-
 +
|colspan="2"|&nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_TRANSFER_ERROR_MASK = BCMSDHOST_SDHSTS_CRC7_ERROR or BCMSDHOST_SDHSTS_CRC16_ERROR or BCMSDHOST_SDHSTS_REW_TIME_OUT or BCMSDHOST_SDHSTS_FIFO_ERROR;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHSTS_ERROR_MASK = BCMSDHOST_SDHSTS_CMD_TIME_OUT or BCMSDHOST_SDHSTS_TRANSFER_ERROR_MASK;</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''BCMSDHOST host configuration register''' <code> BCMSDHOST_SDHCFG_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>BCMSDHOST_SDHCFG_BUSY_IRPT_EN = (1 shl 10);</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHCFG_BLOCK_IRPT_EN = (1 shl 8);</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHCFG_SDIO_IRPT_EN = (1 shl 5);</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHCFG_DATA_IRPT_EN = (1 shl 4);</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHCFG_SLOW_CARD = (1 shl 3);</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHCFG_WIDE_EXT_BUS = (1 shl 2);</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHCFG_WIDE_INT_BUS = (1 shl 1);</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDHCFG_REL_CMD_LINE = (1 shl 0);</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''BCMSDHOST emergency debug mode register''' <code> BCMSDHOST_SDEDM_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FORCE_DATA_MODE = (1 shl 19);</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_CLOCK_PULSE = (1 shl 20);</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_BYPASS = (1 shl 21);</code>
 +
| &nbsp;
 +
|-
 +
|colspan="2"|&nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_WRITE_THRESHOLD_SHIFT = 9;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_READ_THRESHOLD_SHIFT = 14;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_THRESHOLD_MASK = $1f;</code>
 +
| &nbsp;
 +
|-
 +
|colspan="2"|&nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_MASK = $f;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_IDENTMODE = $0;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_DATAMODE = $1;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_READDATA = $2;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_WRITEDATA = $3;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_READWAIT = $4;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_READCRC = $5;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_WRITECRC = $6;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_WRITEWAIT1 = $7;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_POWERDOWN = $8;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_POWERUP = $9;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_WRITESTART1 = $a;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_WRITESTART2 = $b;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_GENPULSES = $c;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_WRITEWAIT2 = $d;</code>
 +
| &nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDEDM_FSM_STARTPOWDOWN = $f;</code>
 +
| &nbsp;
 +
|-
 +
|colspan="2"|&nbsp;
 +
|-
 +
| <code>BCMSDHOST_SDDATA_FIFO_WORDS = 16;</code>
 +
| &nbsp;
 +
|-
 +
|colspan="2"|&nbsp;
 +
|-
 +
| <code>BCMSDHOST_USE_CMD23_FLAGS = (BCMSDHOST_ALLOW_CMD23_READ * MMC_DATA_READ) or (BCMSDHOST_ALLOW_CMD23_WRITE * MMC_DATA_WRITE);</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''BCMSDHOST mailbox constants''' <code> BCMSDHOST_MBOX_TAG_SET_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>BCMSDHOST_MBOX_TAG_SET_SDHOST_CLOCK = $00038042;</code>
 +
| style="width: 50%;"|Tell the firmware the SD Host clock setting so it will be adjusted for changes in core frequency
 +
|-
 +
|}
 +
</div></div>
 +
<br />
  
 
=== Type definitions ===
 
=== Type definitions ===
Line 62: Line 367:
 
| <code>IRQ:LongWord;</code>
 
| <code>IRQ:LongWord;</code>
 
| The IRQ number for this device
 
| The IRQ number for this device
|-
 
| <code>DREQ:LongWord;</code>
 
| The DMA DREQ ID for this device
 
 
|-
 
|-
 
| <code>Lock:TSpinHandle;</code>
 
| <code>Lock:TSpinHandle;</code>
Line 97: Line 399:
 
|-
 
|-
 
| <code>AllowDMA:LongBool;</code>
 
| <code>AllowDMA:LongBool;</code>
| &nbsp;
+
| Allow DMA to be used for data transfers
 
|-
 
|-
 
| <code>ResetClock:LongBool;</code>
 
| <code>ResetClock:LongBool;</code>
Line 114: Line 416:
 
| Offset for data during FIFO drain on DMA read
 
| Offset for data during FIFO drain on DMA read
 
|-
 
|-
| <code>UseDMA:LongBool;</code>
+
| <code>UseSBC:LongBool;</code>
| Use DMA for the current data transfer
+
| Use CMD23 (Set Block Count) for the current transfer
 
|-
 
|-
 
| <code>UseBusy:LongBool;</code>
 
| <code>UseBusy:LongBool;</code>
Line 140: Line 442:
 
| <code>PIOTimeout:LongWord;</code>
 
| <code>PIOTimeout:LongWord;</code>
 
| PIO Read or Write block timeout (in milliseconds)
 
| PIO Read or Write block timeout (in milliseconds)
|-
 
| <code>DMAData:TDMAData;</code>
 
| DMA data descriptor for current request (If applicable)
 
|-
 
| <code>DMADirection:LongWord;</code>
 
| DMA data direction for current request (If applicable)
 
|-
 
| <code>DMABuffer:Pointer;</code>
 
| DMA bounce buffer for the current request (If applicable)
 
 
|-
 
|-
 
|}
 
|}
Line 167: Line 460:
 
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 
<pre style="border: 0; padding-bottom:0px;">procedure BCMSDHOSTInit;</pre>
 
<pre style="border: 0; padding-bottom:0px;">procedure BCMSDHOSTInit;</pre>
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Initialize the BCMSDHOST unit and version table</div>
+
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Initialize the BCMSDHOST unit and parameters</div>
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 
{| class="wikitable" style="font-size: 14px; background: white;"
 
{| class="wikitable" style="font-size: 14px; background: white;"

Latest revision as of 04:45, 29 October 2021

Return to Unit Reference


Description


Broadcom BCM27XX SDHOST Driver unit

The SDHOST controller on the BCM27XX is a non SDHCI-compliant device which requires a specific driver.

It can be routed to GPIO pins 22 to 27 (ALT0) or 48 to 53 (ALT0) in order to control the SD card slot when the SDHCI device is being used for the on board WiFi.

Note that on the Raspberry Pi 4 the SD card is no longer connected to pins 48 to 53 so the SDHOST controller cannot control the primary SD card, there is an additional SDHCI controller (EMMC2) for that purpose.

Constants



[Expand]
BCMSDHOST specific constants BCMSDHOST_*


[Expand]
BCMSDHOST register BCMSDHOST_*


[Expand]
BCMSDHOST command register BCMSDHOST_SDCMD_*


[Expand]
BCMSDHOST clock divider register BCMSDHOST_SDCDIV_*


[Expand]
BCMSDHOST host status register BCMSDHOST_SDHSTS_*


[Expand]
BCMSDHOST host configuration register BCMSDHOST_SDHCFG_*


[Expand]
BCMSDHOST emergency debug mode register BCMSDHOST_SDEDM_*


[Expand]
BCMSDHOST mailbox constants BCMSDHOST_MBOX_TAG_SET_*


Type definitions



BCMSDHOST mailbox tag request

[Expand]

TBCMSDHOSTMailboxTagSetSDHostClock = record

BCMSDHOST host

[Expand]

PBCMSDHOSTHost = ^TBCMSDHOSTHost;

TBCMSDHOSTHost = record


Public variables


None defined

Function declarations



Initialization functions

[Expand]
procedure BCMSDHOSTInit;
Description: Initialize the BCMSDHOST unit and parameters


BCMSDHOST functions

[Expand]
function BCMSDHOSTCreate(Address:PtrUInt; const Name:String; IRQ,DREQ,ClockMinimum,ClockMaximum,GPIOFirst,GPIOLast,GPIOFunction:LongWord; EnableFIQ:Boolean):PSDHCIHost;
Description: Create and register a new BCMSDHOST SDHCI device which can be accessed using the SDHCI API


[Expand]
function BCMSDHOSTDestroy(SDHCI:PSDHCIHost):LongWord;
Description: Stop, deregister and destroy a BCMSDHOST SDHCI device created by this driver


BCMSDHOST MMC functions

[Expand]
function BCMSDHOSTSendCommand(MMC:PMMCDevice; Command:PMMCCommand):LongWord;
Description: Implementation of MMCDeviceSendCommand API for BCMSDHOST SDHCI


[Expand]
function BCMSDHOSTSetIOS(MMC:PMMCDevice):LongWord;
Description: Implementation of MMCDeviceSetIOS API for BCMSDHOST SDHCI


[Expand]
function BCMSDHOSTGetCardDetect(MMC:PMMCDevice):LongWord;
Description: Implementation of MMCDeviceGetCardDetect API for BCMSDHOST SDHCI


[Expand]
function BCMSDHOSTGetWriteProtect(MMC:PMMCDevice):LongWord;
Description: Implementation of MMCDeviceGetWriteProtect API for BCMSDHOST SDHCI


BCMSDHOST SDHCI functions

[Expand]
function BCMSDHOSTHostStart(SDHCI:PSDHCIHost):LongWord;
Description: Implementation of SDHCIHostStart API for BCMSDHOST SDHCI


[Expand]
function BCMSDHOSTHostStop(SDHCI:PSDHCIHost):LongWord;
Description: Implementation of SDHCIHostStop API for BCMSDHOST SDHCI


[Expand]
function BCMSDHOSTReset(SDHCI:PSDHCIHost; Mask:Byte):LongWord;
Description: Implementation of SDHCIReset API for BCMSDHOST SDHCI


[Expand]
function BCMSDHOSTHardwareReset(SDHCI:PSDHCIHost):LongWord;
Description: Implementation of SDHCIHardwareReset API for BCMSDHOST SDHCI


[Expand]
function BCMSDHOSTSetPower(SDHCI:PSDHCIHost; Power:Word):LongWord;
Description: Implementation of SDHCISetPower API for BCMSDHOST SDHCI


[Expand]
function BCMSDHOSTSetClock(SDHCI:PSDHCIHost; Clock:LongWord):LongWord;
Description: Implementation of SDHCISetClock API for BCMSDHOST SDHCI


[Expand]
procedure BCMSDHOSTCommandWaitWorker(SDHCI:PSDHCIHost);
Description: Worker thread task to wait for BCMSDHOST command completion


[Expand]
procedure BCMSDHOSTDMARequestCompleted(Request:PDMARequest);
Description: DMA Request completion callback for the BCMSDHOST host controller


[Expand]
function BCMSDHOSTSharedInterruptHandler(Number,CPUID,Flags:LongWord; SDHCI:PSDHCIHost):LongWord;
Description: Interrupt handler for the BCMSDHOST host controller


BCMSDHOST helper functions

[Expand]
function BCMSDHOSTSetSDHostClock(var Clock,Value1,Value2:LongWord):LongWord;
Description: Set the SD Host Clock value in the Mailbox property tags channel


Return to Unit Reference