GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
if TARGET_COLIBRI_IMX6
|
||||
|
||||
config SYS_BOARD
|
||||
default "colibri_imx6"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "colibri_imx6"
|
||||
|
||||
config SYS_CPU
|
||||
default "armv7"
|
||||
|
||||
config SYS_SOC
|
||||
default "mx6"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "toradex"
|
||||
|
||||
config TDX_CFG_BLOCK
|
||||
default y
|
||||
|
||||
config TDX_HAVE_MMC
|
||||
default y
|
||||
|
||||
config TDX_CFG_BLOCK_DEV
|
||||
default "0"
|
||||
|
||||
config TDX_CFG_BLOCK_PART
|
||||
default "1"
|
||||
|
||||
# Toradex config block in eMMC, at the end of 1st "boot sector"
|
||||
config TDX_CFG_BLOCK_OFFSET
|
||||
default "-512"
|
||||
|
||||
config TDX_CMD_IMX_MFGR
|
||||
bool "Enable factory testing commands for Toradex iMX 6 modules"
|
||||
help
|
||||
This adds the commands
|
||||
pf0100_otp_prog - Program the OTP fuses on the PMIC PF0100
|
||||
If executed on already fused modules it doesn't change any fuse setting.
|
||||
default y
|
||||
|
||||
source "board/toradex/common/Kconfig"
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,9 @@
|
||||
Colibri iMX6
|
||||
M: Max Krummenacher <max.krummenacher@toradex.com>
|
||||
W: http://developer.toradex.com/software/linux/linux-software
|
||||
W: https://www.toradex.com/community
|
||||
S: Maintained
|
||||
F: board/toradex/colibri_imx6/
|
||||
F: include/configs/colibri_imx6.h
|
||||
F: configs/colibri_imx6_defconfig
|
||||
F: arch/arm/dts/imx6-colibri.dts
|
||||
@@ -0,0 +1,5 @@
|
||||
# Copyright (c) 2012-2014 Toradex, Inc.
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
obj-y := colibri_imx6.o do_fuse.o
|
||||
obj-$(CONFIG_TDX_CMD_IMX_MFGR) += pf0100.o
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,97 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2014-2016, Toradex AG
|
||||
*/
|
||||
|
||||
/*
|
||||
* Helpers for i.MX OTP fusing during module production
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
#include <console.h>
|
||||
#include <fuse.h>
|
||||
|
||||
static int mfgr_fuse(void)
|
||||
{
|
||||
unsigned val, val6;
|
||||
|
||||
fuse_sense(0, 5, &val);
|
||||
printf("Fuse 0, 5: %8x\n", val);
|
||||
fuse_sense(0, 6, &val6);
|
||||
printf("Fuse 0, 6: %8x\n", val6);
|
||||
fuse_sense(4, 3, &val);
|
||||
printf("Fuse 4, 3: %8x\n", val);
|
||||
fuse_sense(4, 2, &val);
|
||||
printf("Fuse 4, 2: %8x\n", val);
|
||||
if (val6 & 0x10) {
|
||||
puts("BT_FUSE_SEL already fused, will do nothing\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
/* boot cfg */
|
||||
fuse_prog(0, 5, 0x00005062);
|
||||
/* BT_FUSE_SEL */
|
||||
fuse_prog(0, 6, 0x00000010);
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
int do_mfgr_fuse(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
int ret;
|
||||
puts("Fusing...\n");
|
||||
ret = mfgr_fuse();
|
||||
if (ret == CMD_RET_SUCCESS)
|
||||
puts("done.\n");
|
||||
else
|
||||
puts("failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int do_updt_fuse(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
unsigned val;
|
||||
int ret;
|
||||
int confirmed = argc >= 1 && !strcmp(argv[1], "-y");
|
||||
|
||||
/* can be used in scripts for command availability check */
|
||||
if (argc >= 1 && !strcmp(argv[1], "-n"))
|
||||
return CMD_RET_SUCCESS;
|
||||
|
||||
/* boot cfg */
|
||||
fuse_sense(0, 5, &val);
|
||||
printf("Fuse 0, 5: %8x\n", val);
|
||||
if (val & 0x10) {
|
||||
puts("Fast boot mode already fused, no need to fuse\n");
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
if (!confirmed) {
|
||||
puts("Warning: Programming fuses is an irreversible operation!\n"
|
||||
" Updating to fast boot mode prevents easy\n"
|
||||
" downgrading to previous BSP versions.\n"
|
||||
"\nReally perform this fuse programming? <y/N>\n");
|
||||
if (!confirm_yesno())
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
puts("Fusing fast boot mode...\n");
|
||||
ret = fuse_prog(0, 5, 0x00005072);
|
||||
if (ret == CMD_RET_SUCCESS)
|
||||
puts("done.\n");
|
||||
else
|
||||
puts("failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
mfgr_fuse, 1, 0, do_mfgr_fuse,
|
||||
"OTP fusing during module production",
|
||||
""
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
updt_fuse, 2, 0, do_updt_fuse,
|
||||
"OTP fusing during module update",
|
||||
"updt_fuse [-n] [-y] - boot cfg fast boot mode fusing"
|
||||
);
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
@@ -0,0 +1,267 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2014-2019, Toradex AG
|
||||
*/
|
||||
|
||||
/*
|
||||
* Helpers for Freescale PMIC PF0100
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <asm/arch/iomux.h>
|
||||
#include <asm/arch/mx6-pins.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/mach-imx/iomux-v3.h>
|
||||
|
||||
#include "pf0100_otp.inc"
|
||||
#include "pf0100.h"
|
||||
|
||||
/* define for PMIC register dump */
|
||||
/*#define DEBUG */
|
||||
|
||||
#define WARNBAR "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
|
||||
|
||||
/* use GPIO: EXT_IO1 to switch on VPGM, ON: 1 */
|
||||
static __maybe_unused iomux_v3_cfg_t const pmic_prog_pads[] = {
|
||||
MX6_PAD_NANDF_D3__GPIO2_IO03 | MUX_PAD_CTRL(NO_PAD_CTRL),
|
||||
# define PMIC_PROG_VOLTAGE IMX_GPIO_NR(2, 3)
|
||||
};
|
||||
|
||||
unsigned pmic_init(void)
|
||||
{
|
||||
int rc;
|
||||
struct udevice *dev = NULL;
|
||||
unsigned programmed = 0;
|
||||
uchar bus = 1;
|
||||
uchar devid, revid, val;
|
||||
|
||||
puts("PMIC: ");
|
||||
rc = i2c_get_chip_for_busnum(bus, PFUZE100_I2C_ADDR, 1, &dev);
|
||||
if (rc) {
|
||||
printf("failed to get device for PMIC at address 0x%x\n",
|
||||
PFUZE100_I2C_ADDR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check for errors in PMIC fuses */
|
||||
if (dm_i2c_read(dev, PFUZE100_INTSTAT3, &val, 1) < 0) {
|
||||
puts("i2c pmic INTSTAT3 register read failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (val & PFUZE100_BIT_OTP_ECCI) {
|
||||
puts("\n" WARNBAR);
|
||||
puts("WARNING: ecc errors found in pmic fuse banks\n");
|
||||
puts(WARNBAR);
|
||||
}
|
||||
if (dm_i2c_read(dev, PFUZE100_OTP_ECC_SE1, &val, 1) < 0) {
|
||||
puts("i2c pmic ECC_SE1 register read failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (val & PFUZE100_BITS_ECC_SE1) {
|
||||
puts(WARNBAR);
|
||||
puts("WARNING: ecc has made bit corrections in banks 1 to 5\n");
|
||||
puts(WARNBAR);
|
||||
}
|
||||
if (dm_i2c_read(dev, PFUZE100_OTP_ECC_SE2, &val, 1) < 0) {
|
||||
puts("i2c pmic ECC_SE2 register read failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (val & PFUZE100_BITS_ECC_SE2) {
|
||||
puts(WARNBAR);
|
||||
puts("WARNING: ecc has made bit corrections in banks 6 to 10\n"
|
||||
);
|
||||
puts(WARNBAR);
|
||||
}
|
||||
if (dm_i2c_read(dev, PFUZE100_OTP_ECC_DE1, &val, 1) < 0) {
|
||||
puts("i2c pmic ECC_DE register read failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (val & PFUZE100_BITS_ECC_DE1) {
|
||||
puts(WARNBAR);
|
||||
puts("ERROR: banks 1 to 5 have uncorrectable bits\n");
|
||||
puts(WARNBAR);
|
||||
}
|
||||
if (dm_i2c_read(dev, PFUZE100_OTP_ECC_DE2, &val, 1) < 0) {
|
||||
puts("i2c pmic ECC_DE register read failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (val & PFUZE100_BITS_ECC_DE2) {
|
||||
puts(WARNBAR);
|
||||
puts("ERROR: banks 6 to 10 have uncorrectable bits\n");
|
||||
puts(WARNBAR);
|
||||
}
|
||||
|
||||
/* get device ident */
|
||||
if (dm_i2c_read(dev, PFUZE100_DEVICEID, &devid, 1) < 0) {
|
||||
puts("i2c pmic devid read failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (dm_i2c_read(dev, PFUZE100_REVID, &revid, 1) < 0) {
|
||||
puts("i2c pmic revid read failed\n");
|
||||
return 0;
|
||||
}
|
||||
printf("device id: 0x%.2x, revision id: 0x%.2x, ", devid, revid);
|
||||
|
||||
/* get device programmed state */
|
||||
val = PFUZE100_PAGE_REGISTER_PAGE1;
|
||||
if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) {
|
||||
puts("i2c write failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (dm_i2c_read(dev, PFUZE100_FUSE_POR1, &val, 1) < 0) {
|
||||
puts("i2c fuse_por read failed\n");
|
||||
return 0;
|
||||
}
|
||||
if (val & PFUZE100_FUSE_POR_M)
|
||||
programmed++;
|
||||
|
||||
if (dm_i2c_read(dev, PFUZE100_FUSE_POR2, &val, 1) < 0) {
|
||||
puts("i2c fuse_por read failed\n");
|
||||
return programmed;
|
||||
}
|
||||
if (val & PFUZE100_FUSE_POR_M)
|
||||
programmed++;
|
||||
|
||||
if (dm_i2c_read(dev, PFUZE100_FUSE_POR3, &val, 1) < 0) {
|
||||
puts("i2c fuse_por read failed\n");
|
||||
return programmed;
|
||||
}
|
||||
if (val & PFUZE100_FUSE_POR_M)
|
||||
programmed++;
|
||||
|
||||
switch (programmed) {
|
||||
case 0:
|
||||
puts("not programmed\n");
|
||||
break;
|
||||
case 3:
|
||||
puts("programmed\n");
|
||||
break;
|
||||
default:
|
||||
puts("undefined programming state\n");
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
printf("\t%x", i);
|
||||
for (j = 0; j < 0x80; ) {
|
||||
printf("\n%2x", j);
|
||||
for (i = 0; i < 16; i++) {
|
||||
dm_i2c_read(dev, j + i, &val, 1);
|
||||
printf("\t%2x", val);
|
||||
}
|
||||
j += 0x10;
|
||||
}
|
||||
printf("\nEXT Page 1");
|
||||
|
||||
val = PFUZE100_PAGE_REGISTER_PAGE1;
|
||||
if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) {
|
||||
puts("i2c write failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0x80; j < 0x100; ) {
|
||||
printf("\n%2x", j);
|
||||
for (i = 0; i < 16; i++) {
|
||||
dm_i2c_read(dev, j + i, &val, 1);
|
||||
printf("\t%2x", val);
|
||||
}
|
||||
j += 0x10;
|
||||
}
|
||||
printf("\nEXT Page 2");
|
||||
|
||||
val = PFUZE100_PAGE_REGISTER_PAGE2;
|
||||
if (dm_i2c_write(dev, PFUZE100_PAGE_REGISTER, &val, 1)) {
|
||||
puts("i2c write failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0x80; j < 0x100; ) {
|
||||
printf("\n%2x", j);
|
||||
for (i = 0; i < 16; i++) {
|
||||
dm_i2c_read(dev, j + i, &val, 1);
|
||||
printf("\t%2x", val);
|
||||
}
|
||||
j += 0x10;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
return programmed;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
static int pf0100_prog(void)
|
||||
{
|
||||
int rc;
|
||||
struct udevice *dev = NULL;
|
||||
unsigned char bus = 1;
|
||||
unsigned char val;
|
||||
unsigned int i;
|
||||
|
||||
if (pmic_init() == 3) {
|
||||
puts("PMIC already programmed, exiting\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
/* set up gpio to manipulate vprog, initially off */
|
||||
imx_iomux_v3_setup_multiple_pads(pmic_prog_pads,
|
||||
ARRAY_SIZE(pmic_prog_pads));
|
||||
gpio_direction_output(PMIC_PROG_VOLTAGE, 0);
|
||||
|
||||
rc = i2c_get_chip_for_busnum(bus, PFUZE100_I2C_ADDR, 1, &dev);
|
||||
if (rc) {
|
||||
printf("failed to get device for PMIC at address 0x%x\n",
|
||||
PFUZE100_I2C_ADDR);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pmic_otp_prog); i++) {
|
||||
switch (pmic_otp_prog[i].cmd) {
|
||||
case pmic_i2c:
|
||||
val = (unsigned char) (pmic_otp_prog[i].value & 0xff);
|
||||
if (dm_i2c_write(dev, pmic_otp_prog[i].reg, &val, 1)) {
|
||||
printf("i2c write failed, reg 0x%2x, value 0x%2x\n",
|
||||
pmic_otp_prog[i].reg, val);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
break;
|
||||
case pmic_delay:
|
||||
udelay(pmic_otp_prog[i].value * 1000);
|
||||
break;
|
||||
case pmic_vpgm:
|
||||
gpio_direction_output(PMIC_PROG_VOLTAGE,
|
||||
pmic_otp_prog[i].value);
|
||||
break;
|
||||
case pmic_pwr:
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
}
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static int do_pf0100_prog(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
int ret;
|
||||
puts("Programming PMIC OTP...");
|
||||
ret = pf0100_prog();
|
||||
if (ret == CMD_RET_SUCCESS)
|
||||
puts("done.\n");
|
||||
else
|
||||
puts("failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
pf0100_otp_prog, 1, 0, do_pf0100_prog,
|
||||
"Program the OTP fuses on the PMIC PF0100",
|
||||
""
|
||||
);
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
@@ -0,0 +1,107 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2014-2019, Toradex AG
|
||||
*/
|
||||
|
||||
/*
|
||||
* Helpers for Freescale PMIC PF0100
|
||||
*/
|
||||
|
||||
#ifndef PF0100_H_
|
||||
#define PF0100_H_
|
||||
|
||||
/* bit definitions */
|
||||
#define PFUZE100_BIT_0 (0x01 << 0)
|
||||
#define PFUZE100_BIT_1 (0x01 << 1)
|
||||
#define PFUZE100_BIT_2 (0x01 << 2)
|
||||
#define PFUZE100_BIT_3 (0x01 << 3)
|
||||
#define PFUZE100_BIT_4 (0x01 << 4)
|
||||
#define PFUZE100_BIT_5 (0x01 << 5)
|
||||
#define PFUZE100_BIT_6 (0x01 << 6)
|
||||
#define PFUZE100_BIT_7 (0x01 << 7)
|
||||
|
||||
/* 7-bit I2C bus slave address */
|
||||
#define PFUZE100_I2C_ADDR (0x08)
|
||||
/* Register Addresses */
|
||||
#define PFUZE100_DEVICEID (0x0)
|
||||
#define PFUZE100_REVID (0x3)
|
||||
#define PFUZE100_INTSTAT3 (0xe)
|
||||
#define PFUZE100_BIT_OTP_ECCI PFUZE100_BIT_7
|
||||
#define PFUZE100_SW1AMODE (0x23)
|
||||
#define PFUZE100_SW1ACON 36
|
||||
#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */
|
||||
#define PFUZE100_SW1ACON_SPEED_M (0x3<<6)
|
||||
#define PFUZE100_SW1CCON 49
|
||||
#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */
|
||||
#define PFUZE100_SW1CCON_SPEED_M (0x3<<6)
|
||||
#define PFUZE100_SW1AVOL 32
|
||||
#define PFUZE100_SW1AVOL_VSEL_M (0x3f<<0)
|
||||
#define PFUZE100_SW1CVOL 46
|
||||
#define PFUZE100_SW1CVOL_VSEL_M (0x3f<<0)
|
||||
#define PFUZE100_VGEN1CTL (0x6c)
|
||||
#define PFUZE100_VGEN1_VAL (0x30 + 0x08) /* Always ON, 1.2V */
|
||||
#define PFUZE100_SWBSTCTL (0x66)
|
||||
/* Always ON, Auto Switching Mode, 5.0V */
|
||||
#define PFUZE100_SWBST_VAL (0x40 + 0x08 + 0x00)
|
||||
|
||||
/* chooses the extended page (registers 0x80..0xff) */
|
||||
#define PFUZE100_PAGE_REGISTER 0x7f
|
||||
#define PFUZE100_PAGE_REGISTER_PAGE_M (0x1f << 0)
|
||||
#define PFUZE100_PAGE_REGISTER_PAGE1 (0x01 & PFUZE100_PAGE_REGISTER_PAGE_M)
|
||||
#define PFUZE100_PAGE_REGISTER_PAGE2 (0x02 & PFUZE100_PAGE_REGISTER_PAGE_M)
|
||||
|
||||
/* extended page 1 */
|
||||
#define PFUZE100_OTP_ECC_SE1 0x8a
|
||||
#define PFUZE100_BIT_ECC1_SE PFUZE100_BIT_0
|
||||
#define PFUZE100_BIT_ECC2_SE PFUZE100_BIT_1
|
||||
#define PFUZE100_BIT_ECC3_SE PFUZE100_BIT_2
|
||||
#define PFUZE100_BIT_ECC4_SE PFUZE100_BIT_3
|
||||
#define PFUZE100_BIT_ECC5_SE PFUZE100_BIT_4
|
||||
#define PFUZE100_BITS_ECC_SE1 ((PFUZE100_BIT_ECC1_SE) | \
|
||||
(PFUZE100_BIT_ECC2_SE) | \
|
||||
(PFUZE100_BIT_ECC3_SE) | \
|
||||
(PFUZE100_BIT_ECC4_SE) | \
|
||||
(PFUZE100_BIT_ECC5_SE))
|
||||
#define PFUZE100_OTP_ECC_SE2 0x8b
|
||||
#define PFUZE100_BIT_ECC6_SE PFUZE100_BIT_0
|
||||
#define PFUZE100_BIT_ECC7_SE PFUZE100_BIT_1
|
||||
#define PFUZE100_BIT_ECC8_SE PFUZE100_BIT_2
|
||||
#define PFUZE100_BIT_ECC9_SE PFUZE100_BIT_3
|
||||
#define PFUZE100_BIT_ECC10_SE PFUZE100_BIT_4
|
||||
#define PFUZE100_BITS_ECC_SE2 ((PFUZE100_BIT_ECC6_SE) | \
|
||||
(PFUZE100_BIT_ECC7_SE) | \
|
||||
(PFUZE100_BIT_ECC8_SE) | \
|
||||
(PFUZE100_BIT_ECC9_SE) | \
|
||||
(PFUZE100_BIT_ECC10_SE))
|
||||
#define PFUZE100_OTP_ECC_DE1 0x8c
|
||||
#define PFUZE100_BIT_ECC1_DE PFUZE100_BIT_0
|
||||
#define PFUZE100_BIT_ECC2_DE PFUZE100_BIT_1
|
||||
#define PFUZE100_BIT_ECC3_DE PFUZE100_BIT_2
|
||||
#define PFUZE100_BIT_ECC4_DE PFUZE100_BIT_3
|
||||
#define PFUZE100_BIT_ECC5_DE PFUZE100_BIT_4
|
||||
#define PFUZE100_BITS_ECC_DE1 ((PFUZE100_BIT_ECC1_DE) | \
|
||||
(PFUZE100_BIT_ECC2_DE) | \
|
||||
(PFUZE100_BIT_ECC3_DE) | \
|
||||
(PFUZE100_BIT_ECC4_DE) | \
|
||||
(PFUZE100_BIT_ECC5_DE))
|
||||
#define PFUZE100_OTP_ECC_DE2 0x8d
|
||||
#define PFUZE100_BIT_ECC6_DE PFUZE100_BIT_0
|
||||
#define PFUZE100_BIT_ECC7_DE PFUZE100_BIT_1
|
||||
#define PFUZE100_BIT_ECC8_DE PFUZE100_BIT_2
|
||||
#define PFUZE100_BIT_ECC9_DE PFUZE100_BIT_3
|
||||
#define PFUZE100_BIT_ECC10_DE PFUZE100_BIT_4
|
||||
#define PFUZE100_BITS_ECC_DE2 ((PFUZE100_BIT_ECC6_DE) | \
|
||||
(PFUZE100_BIT_ECC7_DE) | \
|
||||
(PFUZE100_BIT_ECC8_DE) | \
|
||||
(PFUZE100_BIT_ECC9_DE) | \
|
||||
(PFUZE100_BIT_ECC10_DE))
|
||||
#define PFUZE100_FUSE_POR1 0xe4
|
||||
#define PFUZE100_FUSE_POR2 0xe5
|
||||
#define PFUZE100_FUSE_POR3 0xe6
|
||||
#define PFUZE100_FUSE_POR_M (0x1 << 1)
|
||||
|
||||
/* output some informational messages, return the number FUSE_POR=1 */
|
||||
/* i.e. 0: unprogrammed, 3: programmed, other: undefined prog. state */
|
||||
unsigned pmic_init(void);
|
||||
|
||||
#endif /* PF0100_H_ */
|
||||
@@ -0,0 +1,190 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2014-2016, Toradex AG
|
||||
*/
|
||||
|
||||
// Register Output for PF0100 programmer
|
||||
// Customer: Toradex AG
|
||||
// Program: Colibri iMX6 V1.1
|
||||
// Sample marking:
|
||||
// Date: 01.05.2017
|
||||
// Time: 16:22:32
|
||||
// Generated from Spreadsheet Revision: P1.8
|
||||
|
||||
/* sed commands to get from programmer script to struct content */
|
||||
/* sed -e 's/^WRITE_I2C:\(..\):\(..\)/\{pmic_i2c, 0x\1, 0x\2\},/g' -e 's/^DELAY:\([0-9]*\)/\{pmic_delay, 0, \1\},/g' pf0100_otp_Colibri_iMX6.txt > pf0100_otp.inc
|
||||
sed -i -e 's/^VPGM:ON/\{pmic_vpgm, 0, 1},/g' -e 's/^VPGM:OFF/\{pmic_vpgm, 0, 0},/g' pf0100_otp.inc
|
||||
sed -i -e 's/^PWRON: HIGH/\{pmic_pwr, 0, 1},/g' -e 's/^PWRON:LOW/\{pmic_pwr, 0, 0},/g' pf0100_otp.inc
|
||||
*/
|
||||
|
||||
enum { pmic_i2c, pmic_delay, pmic_vpgm, pmic_pwr };
|
||||
struct pmic_otp_prog_t{
|
||||
unsigned char cmd;
|
||||
unsigned char reg;
|
||||
unsigned short value;
|
||||
};
|
||||
|
||||
struct pmic_otp_prog_t pmic_otp_prog[] = {
|
||||
{pmic_i2c, 0x7F, 0x01}, // Access FSL EXT Page 1
|
||||
{pmic_i2c, 0xA0, 0x2B}, // Auto gen from Row94
|
||||
{pmic_i2c, 0xA1, 0x01}, // Auto gen from Row95
|
||||
{pmic_i2c, 0xA2, 0x05}, // Auto gen from Row96
|
||||
{pmic_i2c, 0xA8, 0x2B}, // Auto gen from Row102
|
||||
{pmic_i2c, 0xA9, 0x02}, // Auto gen from Row103
|
||||
{pmic_i2c, 0xAA, 0x01}, // Auto gen from Row104
|
||||
{pmic_i2c, 0xAC, 0x18}, // Auto gen from Row106
|
||||
{pmic_i2c, 0xAE, 0x01}, // Auto gen from Row108
|
||||
{pmic_i2c, 0xB0, 0x2C}, // Auto gen from Row110
|
||||
{pmic_i2c, 0xB1, 0x04}, // Auto gen from Row111
|
||||
{pmic_i2c, 0xB2, 0x01}, // Auto gen from Row112
|
||||
{pmic_i2c, 0xB4, 0x2C}, // Auto gen from Row114
|
||||
{pmic_i2c, 0xB5, 0x04}, // Auto gen from Row115
|
||||
{pmic_i2c, 0xB6, 0x01}, // Auto gen from Row116
|
||||
{pmic_i2c, 0xB8, 0x18}, // Auto gen from Row118
|
||||
{pmic_i2c, 0xBA, 0x01}, // Auto gen from Row120
|
||||
{pmic_i2c, 0xBD, 0x0E}, // Auto gen from Row123
|
||||
{pmic_i2c, 0xC0, 0x06}, // Auto gen from Row126
|
||||
{pmic_i2c, 0xC4, 0x04}, // Auto gen from Row130
|
||||
{pmic_i2c, 0xC8, 0x0E}, // Auto gen from Row134
|
||||
{pmic_i2c, 0xCC, 0x0E}, // Auto gen from Row138
|
||||
{pmic_i2c, 0xCD, 0x05}, // Auto gen from Row139
|
||||
{pmic_i2c, 0xD0, 0x0F}, // Auto gen from Row142
|
||||
{pmic_i2c, 0xD1, 0x05}, // Auto gen from Row143
|
||||
{pmic_i2c, 0xD5, 0x07}, // Auto gen from Row147
|
||||
{pmic_i2c, 0xD8, 0x07}, // Auto gen from Row150
|
||||
{pmic_i2c, 0xD9, 0x06}, // Auto gen from Row151
|
||||
{pmic_i2c, 0xDC, 0x0A}, // Auto gen from Row154
|
||||
{pmic_i2c, 0xDD, 0x03}, // Auto gen from Row155
|
||||
{pmic_i2c, 0xE0, 0x05}, // Auto gen from Row158
|
||||
|
||||
#if 0 /* TBB mode */
|
||||
{pmic_i2c, 0xE4, 0x80}, // TBB_POR = 1
|
||||
{pmic_delay, 0, 10},
|
||||
#else
|
||||
// Write OTP
|
||||
{pmic_i2c, 0xE4, 0x02}, // FUSE POR1=1
|
||||
{pmic_i2c, 0xE5, 0x02}, // FUSE POR2=1
|
||||
{pmic_i2c, 0xE6, 0x02}, // FUSE POR3=1
|
||||
{pmic_i2c, 0xF0, 0x1F}, // Enable ECC for fuse banks 1 to 5 by writing to OTP EN ECC0 register
|
||||
{pmic_i2c, 0xF1, 0x1F}, // Enable ECC for fuse banks 6 to 10 by writing to OTP EN ECC1 register
|
||||
{pmic_i2c, 0x7F, 0x02}, // Access PF0100 EXT Page2
|
||||
{pmic_i2c, 0xD0, 0x1F}, // Set Auto ECC for fuse banks 1 to 5 by writing to OTP AUTO ECC0 register
|
||||
{pmic_i2c, 0xD1, 0x1F}, // Set Auto ECC for fuse banks 6 to 10 by writing to OTP AUTO ECC1 register
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xF1, 0x00}, // Reset Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF2, 0x00}, // Reset Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF3, 0x00}, // Reset Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF4, 0x00}, // Reset Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF5, 0x00}, // Reset Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF6, 0x00}, // Reset Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF7, 0x00}, // Reset Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF8, 0x00}, // Reset Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF9, 0x00}, // Reset Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xFA, 0x00}, // Reset Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_vpgm, 0, 1}, // Turn ON 8V SWBST
|
||||
//VPGM:DOWN:n
|
||||
//VPGM:UP:n
|
||||
{pmic_delay, 0, 500}, // Adds 500msec delay to allow VPGM time to ramp up
|
||||
//-----------------------------------------------------------------------------------
|
||||
// PF0100 OTP MANUAL-PROGRAMMING (BANK 1 thru 10)
|
||||
//-----------------------------------------------------------------------------------
|
||||
// BANK 1
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xF1, 0x00}, // Reset Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF1, 0x03}, // Set Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF1, 0x0B}, // Set Bank 1 ANTIFUSE_EN
|
||||
{pmic_delay, 0, 10}, // Allow time for bank programming to complete
|
||||
{pmic_i2c, 0xF1, 0x03}, // Reset Bank 1 ANTIFUSE_EN
|
||||
{pmic_i2c, 0xF1, 0x00}, // Reset Bank 1 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
// BANK 2
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xF2, 0x00}, // Reset Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF2, 0x03}, // Set Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF2, 0x0B}, // Set Bank 2 ANTIFUSE_EN
|
||||
{pmic_delay, 0, 10}, // Allow time for bank programming to complete
|
||||
{pmic_i2c, 0xF2, 0x03}, // Reset Bank 2 ANTIFUSE_EN
|
||||
{pmic_i2c, 0xF2, 0x00}, // Reset Bank 2 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
// BANK 3
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xF3, 0x00}, // Reset Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF3, 0x03}, // Set Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF3, 0x0B}, // Set Bank 3 ANTIFUSE_EN
|
||||
{pmic_delay, 0, 10}, // Allow time for bank programming to complete
|
||||
{pmic_i2c, 0xF3, 0x03}, // Reset Bank 3 ANTIFUSE_EN
|
||||
{pmic_i2c, 0xF3, 0x00}, // Reset Bank 3 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
// BANK 4
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xF4, 0x00}, // Reset Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF4, 0x03}, // Set Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF4, 0x0B}, // Set Bank 4 ANTIFUSE_EN
|
||||
{pmic_delay, 0, 10}, // Allow time for bank programming to complete
|
||||
{pmic_i2c, 0xF4, 0x03}, // Reset Bank 4 ANTIFUSE_EN
|
||||
{pmic_i2c, 0xF4, 0x00}, // Reset Bank 4 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
// BANK 5
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xF5, 0x00}, // Reset Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF5, 0x03}, // Set Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF5, 0x0B}, // Set Bank 5 ANTIFUSE_EN
|
||||
{pmic_delay, 0, 10}, // Allow time for bank programming to complete
|
||||
{pmic_i2c, 0xF5, 0x03}, // Reset Bank 5 ANTIFUSE_EN
|
||||
{pmic_i2c, 0xF5, 0x00}, // Reset Bank 5 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
// BANK 6
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xF6, 0x00}, // Reset Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF6, 0x03}, // Set Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF6, 0x0B}, // Set Bank 6 ANTIFUSE_EN
|
||||
{pmic_delay, 0, 10}, // Allow time for bank programming to complete
|
||||
{pmic_i2c, 0xF6, 0x03}, // Reset Bank 6 ANTIFUSE_EN
|
||||
{pmic_i2c, 0xF6, 0x00}, // Reset Bank 6 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
// BANK 7
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xF7, 0x00}, // Reset Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF7, 0x03}, // Set Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF7, 0x0B}, // Set Bank 7 ANTIFUSE_EN
|
||||
{pmic_delay, 0, 10}, // Allow time for bank programming to complete
|
||||
{pmic_i2c, 0xF7, 0x03}, // Reset Bank 7 ANTIFUSE_EN
|
||||
{pmic_i2c, 0xF7, 0x00}, // Reset Bank 7 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
// BANK 8
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xF8, 0x00}, // Reset Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF8, 0x03}, // Set Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF8, 0x0B}, // Set Bank 8 ANTIFUSE_EN
|
||||
{pmic_delay, 0, 10}, // Allow time for bank programming to complete
|
||||
{pmic_i2c, 0xF8, 0x03}, // Reset Bank 8 ANTIFUSE_EN
|
||||
{pmic_i2c, 0xF8, 0x00}, // Reset Bank 8 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
// BANK 9
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xF9, 0x00}, // Reset Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF9, 0x03}, // Set Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xF9, 0x0B}, // Set Bank 9 ANTIFUSE_EN
|
||||
{pmic_delay, 0, 10}, // Allow time for bank programming to complete
|
||||
{pmic_i2c, 0xF9, 0x03}, // Reset Bank 9 ANTIFUSE_EN
|
||||
{pmic_i2c, 0xF9, 0x00}, // Reset Bank 9 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
// BANK 10
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_i2c, 0xFA, 0x00}, // Reset Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xFA, 0x03}, // Set Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
{pmic_i2c, 0xFA, 0x0B}, // Set Bank 10 ANTIFUSE_EN
|
||||
{pmic_delay, 0, 10}, // Allow time for bank programming to complete
|
||||
{pmic_i2c, 0xFA, 0x03}, // Reset Bank 10 ANTIFUSE_EN
|
||||
{pmic_i2c, 0xFA, 0x00}, // Reset Bank 10 ANTIFUSE_RW and ANTIFUSE_BYPASS bits
|
||||
//-----------------------------------------------------------------------------------
|
||||
{pmic_vpgm, 0, 0}, // Turn off 8V SWBST
|
||||
{pmic_delay, 0, 500}, // Adds delay to allow VPGM to bleed off
|
||||
{pmic_i2c, 0xD0, 0x00}, // Clear
|
||||
{pmic_i2c, 0xD1, 0x00}, // Clear
|
||||
{pmic_pwr, 0, 0}, // PWRON LOW to reload new OTP data
|
||||
{pmic_delay, 0, 500},
|
||||
{pmic_pwr, 0, 1},
|
||||
#endif
|
||||
};
|
||||
Reference in New Issue
Block a user