9
0
Fork 0

Merge branch 'for-next/imx'

This commit is contained in:
Sascha Hauer 2016-03-11 10:49:49 +01:00
commit 66037e9ed9
13 changed files with 817 additions and 158 deletions

View File

@ -1,2 +1,3 @@
obj-y += board.o
lwl-y += lowlevel.o
obj-y += pmic-ltc3676.o pmic-rn5t567.o pmic-rn5t618.o

View File

@ -16,6 +16,8 @@
* GNU General Public License for more details.
*/
#define pr_fmt(fmt) "Karo-tx6: " fmt
#include <common.h>
#include <gpio.h>
#include <init.h>
@ -26,152 +28,11 @@
#include <mach/bbu.h>
#include <mach/imx6.h>
#include <mfd/imx6q-iomuxc-gpr.h>
#include "pmic.h"
#define ETH_PHY_RST IMX_GPIO_NR(7, 6)
#define ETH_PHY_PWR IMX_GPIO_NR(3, 20)
#define ETH_PHY_INT IMX_GPIO_NR(7, 1)
#define DIV_ROUND(n,d) (((n) + ((d)/2)) / (d))
#define LTC3676_BUCK1 0x01
#define LTC3676_BUCK2 0x02
#define LTC3676_BUCK3 0x03
#define LTC3676_BUCK4 0x04
#define LTC3676_DVB1A 0x0A
#define LTC3676_DVB1B 0x0B
#define LTC3676_DVB2A 0x0C
#define LTC3676_DVB2B 0x0D
#define LTC3676_DVB3A 0x0E
#define LTC3676_DVB3B 0x0F
#define LTC3676_DVB4A 0x10
#define LTC3676_DVB4B 0x11
#define LTC3676_MSKPG 0x13
#define LTC3676_CLIRQ 0x1f
#define LTC3676_BUCK_DVDT_FAST (1 << 0)
#define LTC3676_BUCK_KEEP_ALIVE (1 << 1)
#define LTC3676_BUCK_CLK_RATE_LOW (1 << 2)
#define LTC3676_BUCK_PHASE_SEL (1 << 3)
#define LTC3676_BUCK_ENABLE_300 (1 << 4)
#define LTC3676_BUCK_PULSE_SKIP (0 << 5)
#define LTC3676_BUCK_BURST_MODE (1 << 5)
#define LTC3676_BUCK_CONTINUOUS (2 << 5)
#define LTC3676_BUCK_ENABLE (1 << 7)
#define LTC3676_PGOOD_MASK (1 << 5)
#define LTC3676_MSKPG_BUCK1 (1 << 0)
#define LTC3676_MSKPG_BUCK2 (1 << 1)
#define LTC3676_MSKPG_BUCK3 (1 << 2)
#define LTC3676_MSKPG_BUCK4 (1 << 3)
#define LTC3676_MSKPG_LDO2 (1 << 5)
#define LTC3676_MSKPG_LDO3 (1 << 6)
#define LTC3676_MSKPG_LDO4 (1 << 7)
#define VDD_IO_VAL mV_to_regval(vout_to_vref(3300 * 10, 5))
#define VDD_IO_VAL_LP mV_to_regval(vout_to_vref(3100 * 10, 5))
#define VDD_IO_VAL_2 mV_to_regval(vout_to_vref(3300 * 10, 5_2))
#define VDD_IO_VAL_2_LP mV_to_regval(vout_to_vref(3100 * 10, 5_2))
#define VDD_SOC_VAL mV_to_regval(vout_to_vref(1425 * 10, 6))
#define VDD_SOC_VAL_LP mV_to_regval(vout_to_vref(900 * 10, 6))
#define VDD_DDR_VAL mV_to_regval(vout_to_vref(1500 * 10, 7))
#define VDD_DDR_VAL_LP mV_to_regval(vout_to_vref(1500 * 10, 7))
#define VDD_CORE_VAL mV_to_regval(vout_to_vref(1425 * 10, 8))
#define VDD_CORE_VAL_LP mV_to_regval(vout_to_vref(900 * 10, 8))
/* LDO1 */
#define R1_1 470
#define R2_1 150
/* LDO4 */
#define R1_4 470
#define R2_4 150
/* Buck1 */
#define R1_5 390
#define R2_5 110
#define R1_5_2 470
#define R2_5_2 150
/* Buck2 (SOC) */
#define R1_6 150
#define R2_6 180
/* Buck3 (DDR) */
#define R1_7 150
#define R2_7 140
/* Buck4 (CORE) */
#define R1_8 150
#define R2_8 180
/* calculate voltages in 10mV */
#define R1(idx) R1_##idx
#define R2(idx) R2_##idx
#define vout_to_vref(vout, idx) ((vout) * R2(idx) / (R1(idx) + R2(idx)))
#define vref_to_vout(vref, idx) DIV_ROUND_UP((vref) * (R1(idx) + R2(idx)), R2(idx))
#define mV_to_regval(mV) DIV_ROUND(((((mV) < 4125) ? 4125 : (mV)) - 4125), 125)
#define regval_to_mV(v) (((v) * 125 + 4125))
static struct ltc3673_regs {
u8 addr;
u8 val;
u8 mask;
} ltc3676_regs[] = {
{ LTC3676_MSKPG, ~LTC3676_MSKPG_BUCK1, },
{ LTC3676_DVB2B, VDD_SOC_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
{ LTC3676_DVB3B, VDD_DDR_VAL_LP, ~0x3f, },
{ LTC3676_DVB4B, VDD_CORE_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
{ LTC3676_DVB2A, VDD_SOC_VAL, ~0x3f, },
{ LTC3676_DVB3A, VDD_DDR_VAL, ~0x3f, },
{ LTC3676_DVB4A, VDD_CORE_VAL, ~0x3f, },
{ LTC3676_BUCK1, LTC3676_BUCK_BURST_MODE | LTC3676_BUCK_CLK_RATE_LOW, },
{ LTC3676_BUCK2, LTC3676_BUCK_BURST_MODE, },
{ LTC3676_BUCK3, LTC3676_BUCK_BURST_MODE, },
{ LTC3676_BUCK4, LTC3676_BUCK_BURST_MODE, },
{ LTC3676_CLIRQ, 0, }, /* clear interrupt status */
};
static struct ltc3673_regs ltc3676_regs_2[] = {
{ LTC3676_DVB1B, VDD_IO_VAL_2_LP | LTC3676_PGOOD_MASK, ~0x3f, },
{ LTC3676_DVB1A, VDD_IO_VAL_2, ~0x3f, },
};
static int setup_pmic_voltages(void)
{
struct i2c_adapter *adapter = NULL;
struct i2c_client client;
int addr = 0x3c;
int bus = 0;
int i;
struct ltc3673_regs *r;
adapter = i2c_get_adapter(bus);
if (!adapter) {
pr_err("i2c bus %d not found\n", bus);
return -ENODEV;
}
client.adapter = adapter;
client.addr = addr;
r = ltc3676_regs;
for (i = 0; i < ARRAY_SIZE(ltc3676_regs); i++, r++) {
if (i2c_write_reg(&client, r->addr, &r->val, 1) != 1) {
pr_err("i2c write error\n");
return -EIO;
}
}
r = ltc3676_regs_2;
for (i = 0; i < ARRAY_SIZE(ltc3676_regs_2); i++, r++) {
if (i2c_write_reg(&client, r->addr, &r->val, 1) != 1) {
pr_err("i2c write error\n");
return -EIO;
}
}
return 0;
}
static void eth_init(void)
{
@ -183,19 +44,91 @@ static void eth_init(void)
writel(val, iomux + IOMUXC_GPR1);
}
static struct {
unsigned char addr;
int (*init)(struct i2c_client *client);
const char *name;
} i2c_addrs[] = {
{ 0x3c, ltc3676_pmic_setup, "ltc3676" },
{ 0x32, rn5t618_pmic_setup, "rn5t618" },
{ 0x33, rn5t567_pmic_setup, "rn5t567" },
};
int setup_pmic_voltages(void)
{
struct i2c_adapter *adapter;
struct i2c_client client;
int ret = -ENODEV;
int i;
int bus = 0;
uint8_t reg;
adapter = i2c_get_adapter(bus);
if (!adapter) {
pr_err("i2c bus %d not found\n", bus);
return -ENODEV;
}
client.adapter = adapter;
for (i = 0; i < ARRAY_SIZE(i2c_addrs); i++) {
client.addr = i2c_addrs[i].addr;
pr_debug("Probing for I2C dev 0x%02x\n", client.addr);
ret = i2c_write_reg(&client, 0x00, &reg, 0);
if (ret == 0) {
pr_info("Detected %s PMIC\n", i2c_addrs[i].name);
ret = i2c_addrs[i].init(&client);
goto out;
}
}
pr_err("No PMIC found\n");
out:
if (ret)
pr_err("PMIC setup failed with %s\n", strerror(-ret));
return ret;
}
#define IMX6_SRC_SBMR1 0x04
static int tx6x_devices_init(void)
{
void __iomem *src_base = IOMEM(MX6_SRC_BASE_ADDR);
uint32_t sbmr1;
if (!of_machine_is_compatible("karo,imx6dl-tx6dl") &&
!of_machine_is_compatible("karo,imx6q-tx6q"))
return 0;
barebox_set_hostname("tx6u");
barebox_set_hostname("tx6");
eth_init();
setup_pmic_voltages();
imx6_bbu_nand_register_handler("nand", BBU_HANDLER_FLAG_DEFAULT);
sbmr1 = readl(src_base + IMX6_SRC_SBMR1);
/*
* Check if this board is booted from eMMC or NAND to enable the
* corresponding device. We can't use the regular bootsource
* function here as it might return that we are in serial
* downloader mode. Even if we are SBMR1[7] indicates whether
* this board has eMMC or NAND.
*/
if (sbmr1 & (1 << 7)) {
imx6_bbu_nand_register_handler("nand", BBU_HANDLER_FLAG_DEFAULT);
of_device_enable_and_register_by_name("environment-nand");
of_device_enable_and_register_by_name("gpmi-nand@00112000");
} else {
imx6_bbu_internal_mmc_register_handler("eMMC", "/dev/mmc3.boot0",
BBU_HANDLER_FLAG_DEFAULT);
of_device_enable_and_register_by_name("environment-emmc");
of_device_enable_and_register_by_name("usdhc@0219c000");
}
return 0;
}

View File

@ -0,0 +1,174 @@
soc imx6
loadaddr 0x20000000
dcdofs 0x400
wm 32 0x020e00a4 0x00000016
wm 32 0x020e00c4 0x00000011
wm 32 0x020e03b8 0x0000f079
wm 32 0x020e03d8 0x0000f079
wm 32 0x020e0898 0x00000000
wm 32 0x020e089c 0x00000000
wm 32 0x020e0248 0x00000012
wm 32 0x020e02c8 0x00000015
wm 32 0x020e06b0 0x000030b0
wm 32 0x020e00a0 0x00000015
wm 32 0x020e03b4 0x000030b0
wm 32 0x020e024c 0x00000005
wm 32 0x020e061c 0x000030b0
wm 32 0x020c402c 0x006336c1
wm 32 0x020c4034 0x00012093
wm 32 0x020c4038 0x00012090
wm 32 0x020c80e0 0x00002001
wm 32 0x020c80a0 0x80082029
wm 32 0x020c80b0 0x00065b9a
wm 32 0x020c80c0 0x000f4240
wm 32 0x020e0004 0x48640005
wm 32 0x020e02a8 0x00000001
wm 32 0x020e02ac 0x00000001
wm 32 0x020e0920 0x00000003
wm 32 0x020e02c0 0x00000001
wm 32 0x020e02c4 0x00000001
wm 32 0x020e091c 0x00000003
wm 32 0x020e02ec 0x00000000
wm 32 0x020e05ac 0x00020030
wm 32 0x020e05b4 0x00020030
wm 32 0x020e0528 0x00020030
wm 32 0x020e0520 0x00020030
wm 32 0x020e0514 0x00020030
wm 32 0x020e0510 0x00020030
wm 32 0x020e05bc 0x00020030
wm 32 0x020e05c4 0x00020030
wm 32 0x020e052c 0x00020200
wm 32 0x020e0530 0x00020200
wm 32 0x020e0534 0x00020200
wm 32 0x020e0538 0x00020200
wm 32 0x020e053c 0x00020200
wm 32 0x020e0540 0x00020200
wm 32 0x020e0544 0x00020200
wm 32 0x020e0548 0x00020200
wm 32 0x020e054c 0x00020200
wm 32 0x020e0550 0x00020200
wm 32 0x020e0554 0x00020200
wm 32 0x020e0558 0x00020200
wm 32 0x020e055c 0x00020200
wm 32 0x020e0560 0x00020200
wm 32 0x020e0564 0x00020200
wm 32 0x020e0568 0x00020200
wm 32 0x020e056c 0x00020030
wm 32 0x020e0578 0x00020030
wm 32 0x020e0588 0x00020030
wm 32 0x020e0594 0x00020030
wm 32 0x020e057c 0x00020030
wm 32 0x020e0590 0x00003000
wm 32 0x020e0598 0x00003000
wm 32 0x020e0580 0x00000000
wm 32 0x020e0584 0x00000000
wm 32 0x020e058c 0x00000000
wm 32 0x020e059c 0x00003030
wm 32 0x020e05a0 0x00003030
wm 32 0x020e0784 0x00000030
wm 32 0x020e0788 0x00000030
wm 32 0x020e0794 0x00000030
wm 32 0x020e079c 0x00000030
wm 32 0x020e07a0 0x00000030
wm 32 0x020e07a4 0x00000030
wm 32 0x020e07a8 0x00000030
wm 32 0x020e0748 0x00000030
wm 32 0x020e074c 0x00000030
wm 32 0x020e0750 0x00020000
wm 32 0x020e0758 0x00000000
wm 32 0x020e0774 0x00020000
wm 32 0x020e078c 0x00000030
wm 32 0x020e0798 0x000c0000
wm 32 0x020e0768 0x00002000
wm 32 0x020e0770 0x00000000
wm 32 0x020e0754 0x00000200
wm 32 0x020e075c 0x00000200
wm 32 0x020e0760 0x00000200
wm 32 0x020e0764 0x00000200
wm 32 0x020e076c 0x00000200
wm 32 0x020e0778 0x00000200
wm 32 0x020e077c 0x00000200
wm 32 0x020e0780 0x00000200
wm 32 0x021b001c 0x04008010
wm 32 0x021b001c 0x04008040
wm 32 0x021b0800 0xa1390001
wm 32 0x021b080c 0x001e001e
wm 32 0x021b0810 0x001e001e
wm 32 0x021b480c 0x001e001e
wm 32 0x021b4810 0x001e001e
wm 32 0x021b083c 0x43430349
wm 32 0x021b0840 0x03330334
wm 32 0x021b483c 0x434b0351
wm 32 0x021b4840 0x033d030e
wm 32 0x021b0848 0x40404040
wm 32 0x021b0850 0x40404040
wm 32 0x021b4848 0x40404040
wm 32 0x021b4850 0x40404040
wm 32 0x021b081c 0x33333333
wm 32 0x021b0820 0x33333333
wm 32 0x021b0824 0x33333333
wm 32 0x021b0828 0x33333333
wm 32 0x021b481c 0x33333333
wm 32 0x021b4820 0x33333333
wm 32 0x021b4824 0x33333333
wm 32 0x021b4828 0x33333333
wm 32 0x021b08b8 0x00000800
wm 32 0x021b48b8 0x00000800
wm 32 0x021b0018 0x00000742
check 32 while_all_bits_clear 0x021b0018 0x00000002
wm 32 0x021b001c 0x00008000
check 32 while_any_bit_clear 0x021b001c 0x00004000
wm 32 0x021b0000 0x831a0000
check 32 while_any_bit_clear 0x021b0018 0x40000000
wm 32 0x021b000c 0x545a79a4
wm 32 0x021b0010 0xff538e64
wm 32 0x021b0014 0x01ff00dd
wm 32 0x021b002c 0x000026d2
wm 32 0x021b0030 0x005a1023
wm 32 0x021b0008 0x24444040
wm 32 0x021b0004 0x00020076
wm 32 0x021b0040 0x00000027
wm 32 0x021b001c 0x09308030
wm 32 0x021b001c 0x00048031
wm 32 0x021b001c 0x00488032
wm 32 0x021b001c 0x00008033
wm 32 0x021b0020 0x0000c000
wm 32 0x021b001c 0x00008020
wm 32 0x021b0818 0x00022222
wm 32 0x021b4818 0x00022222
wm 32 0x021b0890 0x00000003
wm 32 0x021b0404 0x00000001
wm 32 0x021b001c 0x04008010
wm 32 0x021b001c 0x04008040
wm 32 0x021b0800 0xa1390001
check 32 while_all_bits_clear 0x021b0800 0x00010000
wm 32 0x021b0800 0xa1380000
wm 32 0x021b001c 0x00048033
wm 32 0x020e05a8 0x00000030
wm 32 0x020e05b0 0x00000030
wm 32 0x020e0524 0x00000030
wm 32 0x020e051c 0x00000030
wm 32 0x020e0518 0x00000030
wm 32 0x020e050c 0x00000030
wm 32 0x020e05b8 0x00000030
wm 32 0x020e05c0 0x00000030
wm 32 0x021b001c 0x04008050
wm 32 0x021b0860 0x00000030
wm 32 0x021b4860 0x00000030
check 32 while_all_bits_clear 0x021b0860 0x0000001f
check 32 while_all_bits_clear 0x021b4860 0x0000001f
wm 32 0x021b001c 0x04008050
wm 32 0x021b0864 0x00000030
check 32 while_all_bits_clear 0x021b0864 0x0000001f
wm 32 0x021b001c 0x04008050
wm 32 0x021b4864 0x00000030
check 32 while_all_bits_clear 0x021b4864 0x0000001f
wm 32 0x021b001c 0x00008033
wm 32 0x021b0800 0xa138002b
wm 32 0x021b0020 0x00001800
wm 32 0x021b0404 0x00001000
wm 32 0x021b0004 0x00025576
wm 32 0x021b001c 0x00000000
check 32 while_all_bits_clear 0x021b001c 0x00004000

View File

@ -18,6 +18,7 @@
#include <asm/barebox-arm.h>
#include <image-metadata.h>
#include <mach/generic.h>
#include <mach/esdctl.h>
#include <linux/sizes.h>
static inline void setup_uart(void)
@ -35,7 +36,7 @@ static inline void setup_uart(void)
putc_ll('>');
}
extern char __dtb_imx6dl_tx6u_801x_start[];
extern char __dtb_imx6dl_tx6u_start[];
BAREBOX_IMD_TAG_STRING(tx6x_mx6_memsize_1G, IMD_TYPE_PARAMETER, "memsize=1024", 0);
@ -52,7 +53,27 @@ ENTRY_FUNCTION(start_imx6dl_tx6x_1g, r0, r1, r2)
if (IS_ENABLED(CONFIG_DEBUG_LL))
setup_uart();
fdt = __dtb_imx6dl_tx6u_801x_start - get_runtime_offset();
fdt = __dtb_imx6dl_tx6u_start - get_runtime_offset();
barebox_arm_entry(0x10000000, SZ_1G, fdt);
}
extern char __dtb_imx6q_tx6q_start[];
ENTRY_FUNCTION(start_imx6q_tx6x_1g, r0, r1, r2)
{
void *fdt;
imx6_cpu_lowlevel_init();
arm_setup_stack(0x00920000 - 8);
IMD_USED(tx6x_mx6_memsize_1G);
if (IS_ENABLED(CONFIG_DEBUG_LL))
setup_uart();
fdt = __dtb_imx6q_tx6q_start - get_runtime_offset();
imx6q_barebox_entry(fdt);
}

View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <i2c/i2c.h>
#include "pmic.h"
#define LTC3676_BUCK1 0x01
#define LTC3676_BUCK2 0x02
#define LTC3676_BUCK3 0x03
#define LTC3676_BUCK4 0x04
#define LTC3676_DVB1A 0x0A
#define LTC3676_DVB1B 0x0B
#define LTC3676_DVB2A 0x0C
#define LTC3676_DVB2B 0x0D
#define LTC3676_DVB3A 0x0E
#define LTC3676_DVB3B 0x0F
#define LTC3676_DVB4A 0x10
#define LTC3676_DVB4B 0x11
#define LTC3676_MSKPG 0x13
#define LTC3676_CLIRQ 0x1f
#define LTC3676_BUCK_DVDT_FAST (1 << 0)
#define LTC3676_BUCK_KEEP_ALIVE (1 << 1)
#define LTC3676_BUCK_CLK_RATE_LOW (1 << 2)
#define LTC3676_BUCK_PHASE_SEL (1 << 3)
#define LTC3676_BUCK_ENABLE_300 (1 << 4)
#define LTC3676_BUCK_PULSE_SKIP (0 << 5)
#define LTC3676_BUCK_BURST_MODE (1 << 5)
#define LTC3676_BUCK_CONTINUOUS (2 << 5)
#define LTC3676_BUCK_ENABLE (1 << 7)
#define LTC3676_PGOOD_MASK (1 << 5)
#define LTC3676_MSKPG_BUCK1 (1 << 0)
#define LTC3676_MSKPG_BUCK2 (1 << 1)
#define LTC3676_MSKPG_BUCK3 (1 << 2)
#define LTC3676_MSKPG_BUCK4 (1 << 3)
#define LTC3676_MSKPG_LDO2 (1 << 5)
#define LTC3676_MSKPG_LDO3 (1 << 6)
#define LTC3676_MSKPG_LDO4 (1 << 7)
#define VDD_IO_VAL mV_to_regval(vout_to_vref(3300 * 10, 5))
#define VDD_IO_VAL_LP mV_to_regval(vout_to_vref(3100 * 10, 5))
#define VDD_IO_VAL_2 mV_to_regval(vout_to_vref(3300 * 10, 5_2))
#define VDD_IO_VAL_2_LP mV_to_regval(vout_to_vref(3100 * 10, 5_2))
#define VDD_SOC_VAL mV_to_regval(vout_to_vref(1425 * 10, 6))
#define VDD_SOC_VAL_LP mV_to_regval(vout_to_vref(900 * 10, 6))
#define VDD_DDR_VAL mV_to_regval(vout_to_vref(1500 * 10, 7))
#define VDD_DDR_VAL_LP mV_to_regval(vout_to_vref(1500 * 10, 7))
#define VDD_CORE_VAL mV_to_regval(vout_to_vref(1425 * 10, 8))
#define VDD_CORE_VAL_LP mV_to_regval(vout_to_vref(900 * 10, 8))
/* LDO1 */
#define R1_1 470
#define R2_1 150
/* LDO4 */
#define R1_4 470
#define R2_4 150
/* Buck1 */
#define R1_5 390
#define R2_5 110
#define R1_5_2 470
#define R2_5_2 150
/* Buck2 (SOC) */
#define R1_6 150
#define R2_6 180
/* Buck3 (DDR) */
#define R1_7 150
#define R2_7 140
/* Buck4 (CORE) */
#define R1_8 150
#define R2_8 180
/* calculate voltages in 10mV */
#define R1(idx) R1_##idx
#define R2(idx) R2_##idx
#define vout_to_vref(vout, idx) ((vout) * R2(idx) / (R1(idx) + R2(idx)))
#define vref_to_vout(vref, idx) DIV_ROUND_UP((vref) * (R1(idx) + R2(idx)), R2(idx))
#define mV_to_regval(mV) DIV_ROUND(((((mV) < 4125) ? 4125 : (mV)) - 4125), 125)
#define regval_to_mV(v) (((v) * 125 + 4125))
static struct ltc3673_regs {
u8 addr;
u8 val;
u8 mask;
} ltc3676_regs[] = {
{ LTC3676_MSKPG, ~LTC3676_MSKPG_BUCK1, },
{ LTC3676_DVB2B, VDD_SOC_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
{ LTC3676_DVB3B, VDD_DDR_VAL_LP, ~0x3f, },
{ LTC3676_DVB4B, VDD_CORE_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
{ LTC3676_DVB2A, VDD_SOC_VAL, ~0x3f, },
{ LTC3676_DVB3A, VDD_DDR_VAL, ~0x3f, },
{ LTC3676_DVB4A, VDD_CORE_VAL, ~0x3f, },
{ LTC3676_BUCK1, LTC3676_BUCK_BURST_MODE | LTC3676_BUCK_CLK_RATE_LOW, },
{ LTC3676_BUCK2, LTC3676_BUCK_BURST_MODE, },
{ LTC3676_BUCK3, LTC3676_BUCK_BURST_MODE, },
{ LTC3676_BUCK4, LTC3676_BUCK_BURST_MODE, },
{ LTC3676_CLIRQ, 0, }, /* clear interrupt status */
};
static struct ltc3673_regs ltc3676_regs_2[] = {
{ LTC3676_DVB1B, VDD_IO_VAL_2_LP | LTC3676_PGOOD_MASK, ~0x3f, },
{ LTC3676_DVB1A, VDD_IO_VAL_2, ~0x3f, },
};
int ltc3676_pmic_setup(struct i2c_client *client)
{
int i;
struct ltc3673_regs *r;
r = ltc3676_regs;
for (i = 0; i < ARRAY_SIZE(ltc3676_regs); i++, r++) {
if (i2c_write_reg(client, r->addr, &r->val, 1) != 1) {
pr_err("i2c write error\n");
return -EIO;
}
}
r = ltc3676_regs_2;
for (i = 0; i < ARRAY_SIZE(ltc3676_regs_2); i++, r++) {
if (i2c_write_reg(client, r->addr, &r->val, 1) != 1) {
pr_err("i2c write error\n");
return -EIO;
}
}
return 0;
}

View File

@ -0,0 +1,158 @@
/*
* Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <i2c/i2c.h>
#include "pmic.h"
#define RN5T567_NOETIMSET 0x11
#define RN5T567_LDORTC1_SLOT 0x2a
#define RN5T567_DC1CTL 0x2c
#define RN5T567_DC1CTL2 0x2d
#define RN5T567_DC2CTL 0x2e
#define RN5T567_DC2CTL2 0x2f
#define RN5T567_DC3CTL 0x30
#define RN5T567_DC3CTL2 0x31
#define RN5T567_DC1DAC 0x36 /* CORE */
#define RN5T567_DC2DAC 0x37 /* SOC */
#define RN5T567_DC3DAC 0x38 /* DDR */
#define RN5T567_DC1DAC_SLP 0x3b
#define RN5T567_DC2DAC_SLP 0x3c
#define RN5T567_DC3DAC_SLP 0x3d
#define RN5T567_LDOEN1 0x44
#define RN5T567_LDODIS 0x46
#define RN5T567_LDOEN2 0x48
#define RN5T567_LDO3DAC 0x4e /* IO */
#define RN5T567_LDORTC1DAC 0x56 /* VBACKUP */
#define NOETIMSET_DIS_OFF_NOE_TIM (1 << 3)
#define VDD_RTC_VAL mV_to_regval_rtc(3000)
#define VDD_HIGH_VAL mV_to_regval3(3000)
#define VDD_HIGH_VAL_LP mV_to_regval3(3000)
#define VDD_CORE_VAL mV_to_regval(1350) /* DCDC1 */
#define VDD_CORE_VAL_LP mV_to_regval(900)
#define VDD_SOC_VAL mV_to_regval(1350) /* DCDC2 */
#define VDD_SOC_VAL_LP mV_to_regval(900)
#define VDD_DDR_VAL mV_to_regval(1350) /* DCDC3 */
#define VDD_DDR_VAL_LP mV_to_regval(1350)
/* calculate voltages in 10mV */
#define v2r(v,n,m) DIV_ROUND(((((v) < (n)) ? (n) : (v)) - (n)), (m))
#define r2v(r,n,m) (((r) * (m) + (n)) / 10)
/* DCDC1-3 */
#define mV_to_regval(mV) v2r((mV) * 10, 6000, 125)
#define regval_to_mV(r) r2v(r, 6000, 125)
/* LDO1-2 */
#define mV_to_regval2(mV) v2r((mV) * 10, 9000, 250)
#define regval2_to_mV(r) r2v(r, 9000, 250)
/* LDO3 */
#define mV_to_regval3(mV) v2r((mV) * 10, 6000, 250)
#define regval3_to_mV(r) r2v(r, 6000, 250)
/* LDORTC */
#define mV_to_regval_rtc(mV) v2r((mV) * 10, 17000, 250)
#define regval_rtc_to_mV(r) r2v(r, 17000, 250)
static struct rn5t567_regs {
u8 addr;
u8 val;
u8 mask;
} rn5t567_regs[] = {
{ RN5T567_NOETIMSET, NOETIMSET_DIS_OFF_NOE_TIM | 0x5, },
{ RN5T567_DC1DAC, VDD_CORE_VAL, },
{ RN5T567_DC2DAC, VDD_SOC_VAL, },
{ RN5T567_DC3DAC, VDD_DDR_VAL, },
{ RN5T567_DC1DAC_SLP, VDD_CORE_VAL_LP, },
{ RN5T567_DC2DAC_SLP, VDD_SOC_VAL_LP, },
{ RN5T567_DC3DAC_SLP, VDD_DDR_VAL_LP, },
{ RN5T567_LDOEN1, 0x01f, ~0x1f, },
{ RN5T567_LDOEN2, 0x10, ~0x30, },
{ RN5T567_LDODIS, 0x00, },
{ RN5T567_LDO3DAC, VDD_HIGH_VAL, },
{ RN5T567_LDORTC1DAC, VDD_RTC_VAL, },
{ RN5T567_LDORTC1_SLOT, 0x0f, ~0x3f, },
};
static int rn5t567_setup_regs(struct i2c_client *client, struct rn5t567_regs *r,
size_t count)
{
int ret;
int i;
for (i = 0; i < count; i++, r++) {
#ifdef DEBUG
unsigned char value;
ret = i2c_read_reg(client, r->addr, &value, 1);
if ((value & ~r->mask) != r->val) {
pr_debug("Changing PMIC reg %02x from %02x to %02x\n",
r->addr, value, r->val);
}
if (ret != 1) {
pr_debug("%s: failed to read PMIC register %02x: %d\n",
__func__, r->addr, ret);
return ret;
}
#endif
ret = i2c_write_reg(client, r->addr, &r->val, 1);
if (ret != 1) {
pr_err("%s: failed to write PMIC register %02x: %d\n",
__func__, r->addr, ret);
return ret;
}
}
return 0;
}
int rn5t567_pmic_setup(struct i2c_client *client)
{
int ret;
unsigned char value;
ret = i2c_read_reg(client, 0x11, &value, 1);
if (ret != 1) {
pr_err("i2c read error\n");
return ret;
}
ret = rn5t567_setup_regs(client, rn5t567_regs,
ARRAY_SIZE(rn5t567_regs));
if (ret)
return ret;
ret = i2c_read_reg(client, RN5T567_DC1DAC, &value, 1);
if (ret == 1) {
pr_debug("VDDCORE set to %umV\n", regval_to_mV(value));
} else {
pr_err("i2c read error\n");
return ret;
}
ret = i2c_read_reg(client, RN5T567_DC2DAC, &value, 1);
if (ret == 1) {
pr_debug("VDDSOC set to %umV\n", regval_to_mV(value));
} else {
pr_err("i2c read error\n");
return ret;
}
return 0;
}

View File

@ -0,0 +1,156 @@
/*
* Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <i2c/i2c.h>
#include "pmic.h"
#define RN5T618_NOETIMSET 0x11
#define RN5T618_LDORTC1_SLOT 0x2a
#define RN5T618_DC1CTL 0x2c
#define RN5T618_DC1CTL2 0x2d
#define RN5T618_DC2CTL 0x2e
#define RN5T618_DC2CTL2 0x2f
#define RN5T618_DC3CTL 0x30
#define RN5T618_DC3CTL2 0x31
#define RN5T618_DC1DAC 0x36 /* CORE */
#define RN5T618_DC2DAC 0x37 /* SOC */
#define RN5T618_DC3DAC 0x38 /* DDR */
#define RN5T618_DC1DAC_SLP 0x3b
#define RN5T618_DC2DAC_SLP 0x3c
#define RN5T618_DC3DAC_SLP 0x3d
#define RN5T618_LDOEN1 0x44
#define RN5T618_LDODIS 0x46
#define RN5T618_LDOEN2 0x48
#define RN5T618_LDO3DAC 0x4e /* IO */
#define RN5T618_LDORTCDAC 0x56 /* VBACKUP */
#define VDD_RTC_VAL mV_to_regval_rtc(3000)
#define VDD_HIGH_VAL mV_to_regval3(3000)
#define VDD_HIGH_VAL_LP mV_to_regval3(3000)
#define VDD_CORE_VAL mV_to_regval(1425) /* DCDC1 */
#define VDD_CORE_VAL_LP mV_to_regval(900)
#define VDD_SOC_VAL mV_to_regval(1425) /* DCDC2 */
#define VDD_SOC_VAL_LP mV_to_regval(900)
#define VDD_DDR_VAL mV_to_regval(1500) /* DCDC3 */
#define VDD_DDR_VAL_LP mV_to_regval(1500)
/* calculate voltages in 10mV */
#define v2r(v,n,m) DIV_ROUND(((((v) < (n)) ? (n) : (v)) - (n)), (m))
#define r2v(r,n,m) (((r) * (m) + (n)) / 10)
/* DCDC1-3 */
#define mV_to_regval(mV) v2r((mV) * 10, 6000, 125)
#define regval_to_mV(r) r2v(r, 6000, 125)
/* LDO1-2 */
#define mV_to_regval2(mV) v2r((mV) * 10, 9000, 250)
#define regval2_to_mV(r) r2v(r, 9000, 250)
/* LDO3 */
#define mV_to_regval3(mV) v2r((mV) * 10, 6000, 250)
#define regval3_to_mV(r) r2v(r, 6000, 250)
/* LDORTC */
#define mV_to_regval_rtc(mV) v2r((mV) * 10, 17000, 250)
#define regval_rtc_to_mV(r) r2v(r, 17000, 250)
static struct rn5t618_regs {
u8 addr;
u8 val;
u8 mask;
} rn5t618_regs[] = {
{ RN5T618_NOETIMSET, 0, },
{ RN5T618_DC1DAC, VDD_CORE_VAL, },
{ RN5T618_DC2DAC, VDD_SOC_VAL, },
{ RN5T618_DC3DAC, VDD_DDR_VAL, },
{ RN5T618_DC1DAC_SLP, VDD_CORE_VAL_LP, },
{ RN5T618_DC2DAC_SLP, VDD_SOC_VAL_LP, },
{ RN5T618_DC3DAC_SLP, VDD_DDR_VAL_LP, },
{ RN5T618_LDOEN1, 0x01f, ~0x1f, },
{ RN5T618_LDOEN2, 0x10, ~0x30, },
{ RN5T618_LDODIS, 0x00, },
{ RN5T618_LDO3DAC, VDD_HIGH_VAL, },
{ RN5T618_LDORTCDAC, VDD_RTC_VAL, },
{ RN5T618_LDORTC1_SLOT, 0x0f, ~0x3f, },
};
static int rn5t618_setup_regs(struct i2c_client *client, struct rn5t618_regs *r,
size_t count)
{
int ret;
int i;
for (i = 0; i < count; i++, r++) {
#ifdef DEBUG
unsigned char value;
ret = i2c_read_reg(client, r->addr, &value, 1);
if ((value & ~r->mask) != r->val) {
pr_debug("Changing PMIC reg %02x from %02x to %02x\n",
r->addr, value, r->val);
}
if (ret != 1) {
pr_debug("%s: failed to read PMIC register %02x: %d\n",
__func__, r->addr, ret);
return ret;
}
#endif
ret = i2c_write_reg(client, r->addr, &r->val, 1);
if (ret != 1) {
pr_err("%s: failed to write PMIC register %02x: %d\n",
__func__, r->addr, ret);
return ret;
}
}
return 0;
}
int rn5t618_pmic_setup(struct i2c_client *client)
{
int ret;
unsigned char value;
ret = i2c_read_reg(client, 0x11, &value, 1);
if (ret) {
pr_err("i2c read error\n");
return ret;
}
ret = rn5t618_setup_regs(client, rn5t618_regs,
ARRAY_SIZE(rn5t618_regs));
if (ret)
return ret;
ret = i2c_read_reg(client, RN5T618_DC1DAC, &value, 1);
if (ret == 1) {
pr_debug("VDDCORE set to %umV\n", regval_to_mV(value));
} else {
pr_err("i2c read error\n");
return ret;
}
ret = i2c_read_reg(client, RN5T618_DC2DAC, &value, 1);
if (ret == 1) {
pr_debug("VDDSOC set to %umV\n", regval_to_mV(value));
} else {
pr_err("i2c read error\n");
return ret;
}
return 0;
}

View File

@ -0,0 +1,8 @@
#include <i2c/i2c.h>
#define DIV_ROUND(n,d) (((n) + ((d)/2)) / (d))
int ltc3676_pmic_setup(struct i2c_client *client);
int rn5t567_pmic_setup(struct i2c_client *client);
int rn5t618_pmic_setup(struct i2c_client *client);

View File

@ -68,7 +68,8 @@ pbl-dtb-$(CONFIG_MACH_TOSHIBA_AC100) += tegra20-paz00.dtb.o
pbl-dtb-$(CONFIG_MACH_TQMA53) += imx53-mba53.dtb.o
pbl-dtb-$(CONFIG_MACH_TQMA6X) += imx6dl-mba6x.dtb.o imx6q-mba6x.dtb.o
pbl-dtb-$(CONFIG_MACH_TX25) += imx25-karo-tx25.dtb.o
pbl-dtb-$(CONFIG_MACH_TX6X) += imx6dl-tx6u-801x.dtb.o
pbl-dtb-$(CONFIG_MACH_TX6X) += imx6dl-tx6u.dtb.o
pbl-dtb-$(CONFIG_MACH_TX6X) += imx6q-tx6q.dtb.o
pbl-dtb-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o
pbl-dtb-$(CONFIG_MACH_USI_TOPKICK) += kirkwood-topkick-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o

View File

@ -0,0 +1,12 @@
/dts-v1/;
#include <arm/imx6q.dtsi>
#include <arm/imx6qdl-tx6.dtsi>
#include "imx6qdl.dtsi"
#include "imx6qdl-tx6x.dtsi"
/ {
model = "Ka-Ro electronics TX6U-801x Module";
compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
};

View File

@ -0,0 +1,12 @@
/dts-v1/;
#include <arm/imx6q.dtsi>
#include <arm/imx6qdl-tx6.dtsi>
#include "imx6q.dtsi"
#include "imx6qdl-tx6x.dtsi"
/ {
model = "Ka-Ro electronics TX6Q Module";
compatible = "karo,imx6q-tx6q", "fsl,imx6q";
};

View File

@ -1,21 +1,32 @@
#include <arm/imx6dl-tx6u-801x.dts>
#include "imx6qdl.dtsi"
/ {
model = "Ka-Ro electronics TX6U-801x Module";
compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
chosen {
linux,stdout-path = &uart1;
environment@0 {
environment-nand {
status = "disabled";
compatible = "barebox,environment";
device-path = &gpmi, "partname:barebox-environment";
};
environment-emmc {
status = "disabled";
compatible = "barebox,environment";
device-path = &usdhc4, "partname:boot1";
};
};
gpio-keys {
status = "disabled";
};
};
&fec {
phy-reset-duration = <22>;
};
&gpmi {
status = "disabled";
partition@0 {
label = "barebox";
reg = <0x0 0x400000>;
@ -53,13 +64,31 @@
MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0b0
>;
};
};
};
&fec {
phy-reset-duration = <22>;
pinctrl_usdhc4: usdhc4grp {
fsl,pins = <
MX6QDL_PAD_SD4_CMD__SD4_CMD 0x070b1
MX6QDL_PAD_SD4_CLK__SD4_CLK 0x070b1
MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x070b1
MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x070b1
MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x070b1
MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x070b1
MX6QDL_PAD_NANDF_ALE__SD4_RESET 0x0b0b1
>;
};
};
};
&ocotp {
barebox,provide-mac-address = <&fec 0x620>;
};
&usdhc4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc4>;
bus-width = <4>;
non-removable;
no-1-8-v;
fsl,wp-controller;
status = "disabled";
};

View File

@ -288,6 +288,11 @@ CFG_start_imx6dl_tx6x_1g.pblx.imximg = $(board)/karo-tx6x/flash-header-tx6dl-1g.
FILE_barebox-karo-imx6dl-tx6x-1g.img = start_imx6dl_tx6x_1g.pblx.imximg
image-$(CONFIG_MACH_TX6X) += barebox-karo-imx6dl-tx6x-1g.img
pblx-$(CONFIG_MACH_TX6X) += start_imx6q_tx6x_1g
CFG_start_imx6q_tx6x_1g.pblx.imximg = $(board)/karo-tx6x/flash-header-tx6q-1g.imxcfg
FILE_barebox-karo-imx6q-tx6x-1g.img = start_imx6q_tx6x_1g.pblx.imximg
image-$(CONFIG_MACH_TX6X) += barebox-karo-imx6q-tx6x-1g.img
pblx-$(CONFIG_MACH_UDOO) += start_imx6_udoo
CFG_start_imx6_udoo.pblx.imximg = $(board)/udoo/flash-header-mx6-udoo.imxcfg
FILE_barebox-udoo-imx6q.img = start_imx6_udoo.pblx.imximg