Blackfin One Time Programmable (OTP) Memory Many Blackfins now have on-chip One Time Programmable (OTP (One Time Programmable (memory))) memory. This document will cover this OTP (One Time Programmable (memory)) memory and is not a general document for any other OTP (One Time Programmable (memory)) flash memory device. The exact size of the OTP (One Time Programmable (memory)) region may vary according to your Blackfin processor variant, so consult the datasheet for exact specifications. The OTP (One Time Programmable (memory)) memory is backed by physical fuses which are “blown” in order to change bit states. Due to the destructive nature of this operation, you can only change bits once. Protection bits and ECC support is included to lock memory from further writing, and to allow for error corrections in case a bit goes bad. The OTP (One Time Programmable (memory)) memory is not directly accessible (in other words, it is not a memory mapped region). Control MMRs are used to communicate with the OTP (One Time Programmable (memory)) peripheral (setting up timings, reading/writing values, etc…). Since programming of the MMRs can be error prone, helper functions have been included in the Boot ROM. This is the only supported method for accessing the OTP (One Time Programmable (memory)) region. The OTP (One Time Programmable (memory)) memory is split up into 128 bit pages. Read/write accesses occur in increments of 64 bit half pages. Often times the pages have predefined meanings (such as the Factory Programmed Settings (FPS) pages), or the Customer Programmable Settings (CPS) pages. The memory is also split up into an “unsecure” region (which means it can be used at any time) and a “secure” region (which means it can only be used when the processor is in “secure” mode). Consult the HRM ((Blackfin) Hardware Reference Manual) for further information on these topics. Accessing secure regions ofOTP (One Time Programmable (memory))is not handled specially for you. In order for it to work, you need to get the processor into secure mode first. While reading theOTP (One Time Programmable (memory))memory allows for flexible operating conditions, writing theOTP (One Time Programmable (memory))memory is not as forgiving. Consult the datasheet to make sure you are operating within specified conditions before attempting to do any write. Boot ROM The Blackfin on-chip ROM contains helper functions for accessing the OTP (One Time Programmable (memory)) memory. We will not discuss this interface further; please refer to the HRM ((Blackfin) Hardware Reference Manual) for your processor variant for more information. uint32_t bfrom_OtpCommand(uint32_t dCommand, uint32_t dValue); uint32_t bfrom_OtpWrite(uint32_t dPage, uint32_t dFlags, uint64_t *pPageContent); uint32_t bfrom_OtpRead(uint32_t dPage, uint32_t dFlags, uint64_t *pPageContent); U-Boot There is a simple otp command to read and write OTP (One Time Programmable (memory)) memory. It follows the typical U-Boot command style and can be found at common/cmd_otp.c. bfin> help otp otp read [count] [half] otp write [--force] [count] [half] - read/write 'count' half-pages starting at page 'page' (offset 'half') Here is an example reading the first 10 half pages and storing the results at address 0x100. bfin> otp read 0x100 0 10 OTP memory read: addr 0x00000100 page 0x000 count 16 ... W...........W... done Linux A simple character device driver has been created so you can read/write OTP (One Time Programmable (memory)) memory from user space. The driver can be found at linux-2.6.x/drivers/char/bfin-otp.c. First enable the driver in your kernel configuration menu. Obviously, you should only enable writing support if you intend on writing OTP (One Time Programmable (memory)). Device Drivers ---> Character devices ---> <*> Blackfin On-Chip OTP Memory Support [ ] Enable writing support of OTP pages While booting, you should see something like: bfin-otp: initialized Then to access the OTP (One Time Programmable (memory)) memory, just open /dev/bfin-otp and use it like a normal character device. Make sure you only do reads/writes in 64 bit increments (8 bytes or 1 half page), and you can use the standard seek functions to select the half page (in units of bytes) you want to start reading from. A quick example is to use dd to read the OTP (One Time Programmable (memory)) memory: root:/> dd if=/dev/bfin-otp of=otp.bin bs=8 count=100 100+0 records in 100+0 records out root:/> ls -l otp.bin -rw-r--r-- 1 root root 800 Jan 1 00:41 otp.bin Notice how the block size was set to 8 bytes (or 64 bits). Any other increment will result in an error since the ROM functions only support reading in chunks of half pages. Writing Before you can write to the device, you have to initiate a simple unlock ioctl. This is to prevent inadvertent writes and has no relation to the OTP (One Time Programmable (memory))_LOCK operation. Once you've opened the device and have a file descriptor, issue: #include #include ... ioctl(fd, MEMUNLOCK); Then use the normal write and lseek functions to write out data. The same limitation mentioned above with valid lengths applies here as well. You can only program half-pages at a time, so it is up to you to handle this. The kernel will not split up/overlay writes for you. Conversely, once you've finished writing, you should inform the kernel by doing: ioctl(fd, MEMLOCK); Page Locking If you wish to lock a page in OTP (One Time Programmable (memory)) (the OTP (One Time Programmable (memory))_LOCK operation), then you can use the OTPLOCK ioctl: #include #include ... ioctl(fd, OTPLOCK, 0x1C); This will lock page 0x1C in OTP (One Time Programmable (memory)).