From patchwork Thu Sep 19 08:09:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: zhangqing X-Patchwork-Id: 1164436 X-Patchwork-Delegate: philipp.tomsich@theobroma-systems.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=rock-chips.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 46YrDw2gz5z9sNk for ; Thu, 19 Sep 2019 18:51:44 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 40FB8C21DB5; Thu, 19 Sep 2019 08:11:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=RCVD_IN_SORBS_WEB autolearn=no autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 7B660C21E62; Thu, 19 Sep 2019 08:11:24 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id EF3DDC21DCA; Thu, 19 Sep 2019 08:09:53 +0000 (UTC) Received: from regular1.263xmail.com (regular1.263xmail.com [211.150.70.204]) by lists.denx.de (Postfix) with ESMTPS id 61A62C21E0D for ; Thu, 19 Sep 2019 08:09:50 +0000 (UTC) Received: from zhangqing?rock-chips.com (unknown [192.168.167.70]) by regular1.263xmail.com (Postfix) with ESMTP id 84257296; Thu, 19 Sep 2019 16:09:47 +0800 (CST) X-263anti-spam: KSV:0;BIG:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ADDR-CHECKED4: 1 X-ABS-CHECKED: 1 X-SKE-CHECKED: 1 X-ANTISPAM-LEVEL: 2 Received: from localhost.localdomain (unknown [58.22.7.114]) by smtp.263.net (postfix) whith ESMTP id P8143T139957471536896S1568880584428358_; Thu, 19 Sep 2019 16:09:46 +0800 (CST) X-IP-DOMAINF: 1 X-UNIQUE-TAG: <3b7c1595c6b9da851b12c036d7afac61> X-RL-SENDER: zhangqing@rock-chips.com X-SENDER: zhangqing@rock-chips.com X-LOGIN-NAME: zhangqing@rock-chips.com X-FST-TO: yk@rock-chips.com X-SENDER-IP: 58.22.7.114 X-ATTACHMENT-NUM: 0 X-DNS-TYPE: 0 From: Elaine Zhang To: kever.yang@rock-chips.com, chenjh@rock-chips.com Date: Thu, 19 Sep 2019 16:09:53 +0800 Message-Id: <1568880593-23201-1-git-send-email-zhangqing@rock-chips.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1568880493-22962-1-git-send-email-zhangqing@rock-chips.com> References: <1568880493-22962-1-git-send-email-zhangqing@rock-chips.com> Cc: Elaine Zhang , u-boot@lists.denx.de, jack@embed.me.uk, krzk@kernel.org, sven@svenschwermer.de, richard@puffinpack.se Subject: [U-Boot] [PATCH v3 8/8] power: pmic: rk809: support rk809 pmic X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: Joseph Chen The RK809 is a Power Management IC (PMIC) for multimedia and handheld devices. They contains the following components: - Regulators(5*BUCKs, 9*LDOs, 2*SWITCHs) - RTC - Clocking Signed-off-by: Joseph Chen Signed-off-by: Elaine Zhang --- drivers/power/pmic/rk8xx.c | 6 +++- drivers/power/regulator/rk8xx.c | 70 ++++++++++++++++++++++++++++++++++++++++- include/power/rk8xx_pmic.h | 1 + 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c index 0ec6cb31d706..3e256377079a 100644 --- a/drivers/power/pmic/rk8xx.c +++ b/drivers/power/pmic/rk8xx.c @@ -73,6 +73,7 @@ static int rk8xx_shutdown(struct udevice *dev) devctrl_reg = REG_DEVCTRL; dev_off = BIT(0); break; + case RK809_ID: case RK817_ID: devctrl_reg = RK817_REG_SYS_CFG3; dev_off = BIT(0); @@ -136,7 +137,8 @@ static int rk8xx_probe(struct udevice *dev) u8 value; /* read Chip variant */ - if (device_is_compatible(dev, "rockchip,rk817")) { + if (device_is_compatible(dev, "rockchip,rk817") || + device_is_compatible(dev, "rockchip,rk809")) { id_msb = RK817_ID_MSB; id_lsb = RK817_ID_LSB; } else { @@ -163,6 +165,7 @@ static int rk8xx_probe(struct udevice *dev) on_source = RK8XX_ON_SOURCE; off_source = RK8XX_OFF_SOURCE; break; + case RK809_ID: case RK817_ID: on_source = RK817_ON_SOURCE; off_source = RK817_OFF_SOURCE; @@ -218,6 +221,7 @@ static struct dm_pmic_ops rk8xx_ops = { static const struct udevice_id rk8xx_ids[] = { { .compatible = "rockchip,rk805" }, { .compatible = "rockchip,rk808" }, + { .compatible = "rockchip,rk809" }, { .compatible = "rockchip,rk816" }, { .compatible = "rockchip,rk817" }, { .compatible = "rockchip,rk818" }, diff --git a/drivers/power/regulator/rk8xx.c b/drivers/power/regulator/rk8xx.c index 3c4a18b0f0c7..194086c6d240 100644 --- a/drivers/power/regulator/rk8xx.c +++ b/drivers/power/regulator/rk8xx.c @@ -27,6 +27,10 @@ #define RK808_BUCK4_VSEL_MASK 0xf #define RK808_LDO_VSEL_MASK 0x1f +/* RK809 BUCK5 */ +#define RK809_BUCK5_CONFIG(n) (0xde + (n) * 1) +#define RK809_BUCK5_VSEL_MASK 0x07 + /* RK817 BUCK */ #define RK817_BUCK_ON_VSEL(n) (0xbb + 3 * (n - 1)) #define RK817_BUCK_SLP_VSEL(n) (0xbc + 3 * (n - 1)) @@ -59,6 +63,7 @@ #define RK805_RAMP_RATE_6MV_PER_US (1 << RK805_RAMP_RATE_OFFSET) #define RK805_RAMP_RATE_12_5MV_PER_US (2 << RK805_RAMP_RATE_OFFSET) #define RK805_RAMP_RATE_25MV_PER_US (3 << RK805_RAMP_RATE_OFFSET) + #define RK808_RAMP_RATE_OFFSET 3 #define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) #define RK808_RAMP_RATE_2MV_PER_US (0 << RK808_RAMP_RATE_OFFSET) @@ -105,6 +110,14 @@ static const struct rk8xx_reg_info rk816_buck[] = { { 800000, 100000, REG_BUCK4_ON_VSEL, REG_BUCK4_SLP_VSEL, REG_BUCK4_CONFIG, RK818_BUCK4_VSEL_MASK, }, }; +static const struct rk8xx_reg_info rk809_buck5[] = { + /* buck 5 */ + { 1500000, 0, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x00, }, + { 1800000, 200000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x01, }, + { 2800000, 200000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x04, }, + { 3300000, 300000, RK809_BUCK5_CONFIG(0), RK809_BUCK5_CONFIG(1), NA, RK809_BUCK5_VSEL_MASK, 0x06, }, +}; + static const struct rk8xx_reg_info rk817_buck[] = { /* buck 1 */ { 500000, 12500, RK817_BUCK_ON_VSEL(1), RK817_BUCK_SLP_VSEL(1), RK817_BUCK_CONFIG(1), RK817_BUCK_VSEL_MASK, 0x00, }, @@ -223,6 +236,7 @@ static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic, return &rk816_buck[num + 4]; } + case RK809_ID: case RK817_ID: switch (num) { case 0 ... 2: @@ -239,6 +253,16 @@ static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic, return &rk817_buck[num * 3 + 1]; else return &rk817_buck[num * 3 + 2]; + /* BUCK5 for RK809 */ + default: + if (uvolt < 1800000) + return &rk809_buck5[0]; + else if (uvolt < 2800000) + return &rk809_buck5[1]; + else if (uvolt < 3300000) + return &rk809_buck5[2]; + else + return &rk809_buck5[3]; } case RK818_ID: return &rk818_buck[num]; @@ -308,6 +332,7 @@ static int _buck_set_enable(struct udevice *pmic, int buck, bool enable) ret = pmic_clrsetbits(pmic, REG_DCDC_EN, mask, enable ? mask : 0); break; + case RK809_ID: case RK817_ID: if (buck < 4) { if (enable) @@ -315,6 +340,13 @@ static int _buck_set_enable(struct udevice *pmic, int buck, bool enable) else value = ((0 << buck) | (1 << (buck + 4))); ret = pmic_reg_write(pmic, RK817_POWER_EN(0), value); + /* BUCK5 for RK809 */ + } else { + if (enable) + value = ((1 << 1) | (1 << 5)); + else + value = ((0 << 1) | (1 << 5)); + ret = pmic_reg_write(pmic, RK817_POWER_EN(3), value); } break; default: @@ -369,10 +401,15 @@ static int _buck_get_enable(struct udevice *pmic, int buck) if (ret < 0) return ret; break; + case RK809_ID: case RK817_ID: if (buck < 4) { mask = 1 << buck; ret = pmic_reg_read(pmic, RK817_POWER_EN(0)); + /* BUCK5 for RK809 */ + } else { + mask = 1 << 1; + ret = pmic_reg_read(pmic, RK817_POWER_EN(3)); } break; } @@ -402,9 +439,12 @@ static int _buck_set_suspend_enable(struct udevice *pmic, int buck, bool enable) ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF1, mask, enable ? 0 : mask); break; + case RK809_ID: case RK817_ID: if (buck < 4) mask = 1 << buck; + else + mask = 1 << 5; /* BUCK5 for RK809 */ ret = pmic_clrsetbits(pmic, RK817_POWER_SLP_EN(0), mask, enable ? mask : 0); break; @@ -438,9 +478,12 @@ static int _buck_get_suspend_enable(struct udevice *pmic, int buck) return val; ret = val & mask ? 0 : 1; break; + case RK809_ID: case RK817_ID: if (buck < 4) mask = 1 << buck; + else + mask = 1 << 5; /* BUCK5 for RK809 */ val = pmic_reg_read(pmic, RK817_POWER_SLP_EN(0)); if (val < 0) @@ -463,6 +506,7 @@ static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic, case RK805_ID: case RK816_ID: return &rk816_ldo[num]; + case RK809_ID: case RK817_ID: if (uvolt < 3400000) return &rk817_ldo[num * 2 + 0]; @@ -499,6 +543,7 @@ static int _ldo_get_enable(struct udevice *pmic, int ldo) if (ret < 0) return ret; break; + case RK809_ID: case RK817_ID: if (ldo < 4) { mask = 1 << ldo; @@ -521,7 +566,6 @@ static int _ldo_get_enable(struct udevice *pmic, int ldo) return ret & mask ? true : false; } - static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable) { struct rk8xx_priv *priv = dev_get_priv(pmic); @@ -550,6 +594,7 @@ static int _ldo_set_enable(struct udevice *pmic, int ldo, bool enable) ret = pmic_clrsetbits(pmic, REG_LDO_EN, mask, enable ? mask : 0); break; + case RK809_ID: case RK817_ID: if (ldo < 4) { en_reg = RK817_POWER_EN(1); @@ -592,6 +637,7 @@ static int _ldo_set_suspend_enable(struct udevice *pmic, int ldo, bool enable) ret = pmic_clrsetbits(pmic, REG_SLEEP_SET_OFF2, mask, enable ? 0 : mask); break; + case RK809_ID: case RK817_ID: if (ldo == 8) { mask = 1 << 4; /* LDO9 */ @@ -631,6 +677,7 @@ static int _ldo_get_suspend_enable(struct udevice *pmic, int ldo) return val; ret = val & mask ? 0 : 1; break; + case RK809_ID: case RK817_ID: if (ldo == 8) { mask = 1 << 4; /* LDO9 */ @@ -850,6 +897,11 @@ static int switch_set_enable(struct udevice *dev, bool enable) ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask, enable ? mask : 0); break; + case RK809_ID: + mask = (1 << (sw + 2)) | (1 << (sw + 6)); + ret = pmic_clrsetbits(dev->parent, RK817_POWER_EN(3), mask, + enable ? mask : 0); + break; case RK818_ID: mask = 1 << 6; ret = pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask, @@ -874,6 +926,10 @@ static int switch_get_enable(struct udevice *dev) mask = 1 << (sw + 5); ret = pmic_reg_read(dev->parent, REG_DCDC_EN); break; + case RK809_ID: + mask = 1 << (sw + 2); + ret = pmic_reg_read(dev->parent, RK817_POWER_EN(3)); + break; case RK818_ID: mask = 1 << 6; ret = pmic_reg_read(dev->parent, REG_DCDC_EN); @@ -908,6 +964,11 @@ static int switch_set_suspend_enable(struct udevice *dev, bool enable) ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask, enable ? 0 : mask); break; + case RK809_ID: + mask = 1 << (sw + 6); + ret = pmic_clrsetbits(dev->parent, RK817_POWER_SLP_EN(0), mask, + enable ? mask : 0); + break; case RK818_ID: mask = 1 << 6; ret = pmic_clrsetbits(dev->parent, REG_SLEEP_SET_OFF1, mask, @@ -935,6 +996,13 @@ static int switch_get_suspend_enable(struct udevice *dev) return val; ret = val & mask ? 0 : 1; break; + case RK809_ID: + mask = 1 << (sw + 6); + val = pmic_reg_read(dev->parent, RK817_POWER_SLP_EN(0)); + if (val < 0) + return val; + ret = val & mask ? 1 : 0; + break; case RK818_ID: mask = 1 << 6; val = pmic_reg_read(dev->parent, REG_SLEEP_SET_OFF1); diff --git a/include/power/rk8xx_pmic.h b/include/power/rk8xx_pmic.h index d93cecedddf7..8ff0af35c57a 100644 --- a/include/power/rk8xx_pmic.h +++ b/include/power/rk8xx_pmic.h @@ -185,6 +185,7 @@ enum { enum { RK805_ID = 0x8050, RK808_ID = 0x0000, + RK809_ID = 0x8090, RK816_ID = 0x8160, RK817_ID = 0x8170, RK818_ID = 0x8180,