From patchwork Mon Feb 1 08:54:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Wu X-Patchwork-Id: 576377 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 218E1140326 for ; Mon, 1 Feb 2016 19:56:59 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aQAGB-00057i-Oi; Mon, 01 Feb 2016 08:54:59 +0000 Received: from lucky1.263xmail.com ([211.157.147.133]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aQAG6-0004yI-M8; Mon, 01 Feb 2016 08:54:56 +0000 Received: from wdc?rock-chips.com (unknown [192.168.167.228]) by lucky1.263xmail.com (Postfix) with SMTP id 5C6624EAF2; Mon, 1 Feb 2016 16:54:29 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 1 X-MAIL-DELIVERY: 0 X-KSVirus-check: 0 X-ABS-CHECKED: 4 X-ADDR-CHECKED: 0 Received: from [172.16.12.228] (localhost.localdomain [127.0.0.1]) by smtp.263.net (Postfix) with ESMTP id C40EAC62; Mon, 1 Feb 2016 16:54:26 +0800 (CST) X-RL-SENDER: wdc@rock-chips.com X-FST-TO: linux-kernel@vger.kernel.org X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: wdc@rock-chips.com X-UNIQUE-TAG: <90695d939dd35bbe2c7d32020e749340> X-ATTACHMENT-NUM: 1 X-SENDER: wdc@rock-chips.com X-DNS-TYPE: 0 Received: from [172.16.12.228] (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith ESMTP id 31441MLPT3T; Mon, 01 Feb 2016 16:54:28 +0800 (CST) Subject: Re: [PATCH] PM / AVS: rockchip-io: add GRF and PMUGRF types to distinguish To: Heiko Stuebner , David Wu References: <1454155305-55516-1-git-send-email-david.wu@rock-chips.com> <5387650.lAgTxexlF2@phil> From: "David.Wu" Message-ID: <56AF1D4E.40307@rock-chips.com> Date: Mon, 1 Feb 2016 16:54:38 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.5.0 MIME-Version: 1.0 In-Reply-To: <5387650.lAgTxexlF2@phil> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160201_005455_463723_21C0CA48 X-CRM114-Status: GOOD ( 20.30 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [211.157.147.133 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nm@ti.com, huangtao@rock-chips.com, khilman@kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, zyw@rock-chips.com, xjq@rock-chips.com, cf@rock-chips.com, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org Hi Heiko, 在 2016/1/30 20:39, Heiko Stuebner 写道: > Hi David, > > Am Samstag, 30. Januar 2016, 20:01:45 schrieb David Wu: >> As rk3368 contained two separated iodomain areas, this was >> determined to use which regmap base address. >> >> Signed-off-by: David Wu > I don't think we need to specify this on a driver level. Both GRF areas are > "General register files" only located in two separate power-domains. > So the rockchip,grf property should work for both. Especially as nothing > keeps designers from introducing yet another GRF-area somewhere else ;-) > > >From when I started working on the rk3368, I still have a preliminary > patches for that sitting here, so I've attached on how I envisoned that to > work. Okay, i agree to you, but it make someone a little confused just from the drive code, not DT file, about pmugrf regmap base address.:-) How do you feel about intergating GRF and PMU drivers in one driver? Thanks! > > Heiko > >> --- >> drivers/power/avs/rockchip-io-domain.c | 32 >> ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 >> deletions(-) >> >> diff --git a/drivers/power/avs/rockchip-io-domain.c >> b/drivers/power/avs/rockchip-io-domain.c index 8099456..b17aeb7 100644 >> --- a/drivers/power/avs/rockchip-io-domain.c >> +++ b/drivers/power/avs/rockchip-io-domain.c >> @@ -47,6 +47,11 @@ >> #define RK3368_SOC_CON15_FLASH0 BIT(14) >> #define RK3368_SOC_FLASH_SUPPLY_NUM 2 >> >> +enum rockchip_iodomain_grf_type { >> + GRF, >> + PMUGRF >> +}; >> + >> struct rockchip_iodomain; >> >> /** >> @@ -54,6 +59,7 @@ struct rockchip_iodomain; >> */ >> struct rockchip_iodomain_soc_data { >> int grf_offset; >> + enum rockchip_iodomain_grf_type type; >> const char *supply_names[MAX_SUPPLIES]; >> void (*init)(struct rockchip_iodomain *iod); >> }; >> @@ -67,7 +73,7 @@ struct rockchip_iodomain_supply { >> >> struct rockchip_iodomain { >> struct device *dev; >> - struct regmap *grf; >> + struct regmap *base; >> struct rockchip_iodomain_soc_data *soc_data; >> struct rockchip_iodomain_supply supplies[MAX_SUPPLIES]; >> }; >> @@ -86,7 +92,7 @@ static int rockchip_iodomain_write(struct >> rockchip_iodomain_supply *supply, /* apply hiword-mask */ >> val |= (BIT(supply->idx) << 16); >> >> - ret = regmap_write(iod->grf, iod->soc_data->grf_offset, val); >> + ret = regmap_write(iod->base, iod->soc_data->grf_offset, val); >> if (ret) >> dev_err(iod->dev, "Couldn't write to GRF\n"); >> >> @@ -157,7 +163,7 @@ static void rk3288_iodomain_init(struct >> rockchip_iodomain *iod) * instead of a special gpio. >> */ >> val = RK3288_SOC_CON2_FLASH0 | (RK3288_SOC_CON2_FLASH0 << 16); >> - ret = regmap_write(iod->grf, RK3288_SOC_CON2, val); >> + ret = regmap_write(iod->base, RK3288_SOC_CON2, val); >> if (ret < 0) >> dev_warn(iod->dev, "couldn't update flash0 ctrl\n"); >> } >> @@ -176,7 +182,7 @@ static void rk3368_iodomain_init(struct >> rockchip_iodomain *iod) * instead of a special gpio. >> */ >> val = RK3368_SOC_CON15_FLASH0 | (RK3368_SOC_CON15_FLASH0 << 16); >> - ret = regmap_write(iod->grf, RK3368_SOC_CON15, val); >> + ret = regmap_write(iod->base, RK3368_SOC_CON15, val); >> if (ret < 0) >> dev_warn(iod->dev, "couldn't update flash0 ctrl\n"); >> } >> @@ -187,6 +193,7 @@ static void rk3368_iodomain_init(struct >> rockchip_iodomain *iod) */ >> static const struct rockchip_iodomain_soc_data soc_data_rk3188 = { >> .grf_offset = 0x104, >> + .type = GRF, >> .supply_names = { >> NULL, >> NULL, >> @@ -209,6 +216,7 @@ static const struct rockchip_iodomain_soc_data >> soc_data_rk3188 = { >> >> static const struct rockchip_iodomain_soc_data soc_data_rk3288 = { >> .grf_offset = 0x380, >> + .type = GRF, >> .supply_names = { >> "lcdc", /* LCDC_VDD */ >> "dvp", /* DVPIO_VDD */ >> @@ -226,6 +234,7 @@ static const struct rockchip_iodomain_soc_data >> soc_data_rk3288 = { >> >> static const struct rockchip_iodomain_soc_data soc_data_rk3368 = { >> .grf_offset = 0x900, >> + .type = GRF, >> .supply_names = { >> NULL, /* reserved */ >> "dvp", /* DVPIO_VDD */ >> @@ -242,6 +251,7 @@ static const struct rockchip_iodomain_soc_data >> soc_data_rk3368 = { >> >> static const struct rockchip_iodomain_soc_data soc_data_rk3368_pmu = { >> .grf_offset = 0x100, >> + .type = PMUGRF, >> .supply_names = { >> NULL, >> NULL, >> @@ -293,10 +303,16 @@ static int rockchip_iodomain_probe(struct >> platform_device *pdev) match = of_match_node(rockchip_iodomain_match, >> np); >> iod->soc_data = (struct rockchip_iodomain_soc_data *)match->data; >> >> - iod->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); >> - if (IS_ERR(iod->grf)) { >> - dev_err(&pdev->dev, "couldn't find grf regmap\n"); >> - return PTR_ERR(iod->grf); >> + if (iod->soc_data->type == PMUGRF) >> + iod->base = syscon_regmap_lookup_by_phandle( >> + np, "rockchip,pmugrf"); >> + else >> + iod->base = syscon_regmap_lookup_by_phandle( >> + np, "rockchip,grf"); >> + if (IS_ERR(iod->base)) { >> + dev_err(&pdev->dev, "couldn't find %s regmap\n", >> + (iod->soc_data->type == PMUGRF) ? "pmugrf" : "grf"); >> + return PTR_ERR(iod->base); >> } >> >> for (i = 0; i < MAX_SUPPLIES; i++) { From 73cc56277c42fd13bed3921b07c84ac4b030321a Mon Sep 17 00:00:00 2001 From: David Wu Date: Wed, 24 Dec 2014 16:31:09 +0800 Subject: [PATCH 1/5] rk3368: io-domain: add io domain volt sel Content-Type: text/plain; charset="utf-8" Signed-off-by: David Wu --- drivers/power/avs/rockchip-io-domain.c | 184 +++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 54 deletions(-) diff --git a/drivers/power/avs/rockchip-io-domain.c b/drivers/power/avs/rockchip-io-domain.c index b160132..d096457 100755 --- a/drivers/power/avs/rockchip-io-domain.c +++ b/drivers/power/avs/rockchip-io-domain.c @@ -43,19 +43,28 @@ #define RK3288_SOC_CON2_FLASH0 BIT(7) #define RK3288_SOC_FLASH_SUPPLY_NUM 2 -#define RK3368_GRF_SOC_CON15 0x43c -#define RK3368_GRF_SOC_CON15_FLASH0 BIT(14) +#define RK3368_GRF_SOC_CON15 0x43c +#define RK3368_GRF_SOC_CON15_FLASH0 BIT(14) #define RK3368_SOC_FLASH_SUPPLY_NUM 2 +#define MAX_ROCKCHIP_GRF_NUM 2 struct rockchip_iodomain; /** * @supplies: voltage settings matching the register bits. */ + +enum rockchip_iodomain_grf_type { + GRF, + PMU_GRF, +}; + struct rockchip_iodomain_soc_data { int grf_offset; - const char *supply_names[MAX_SUPPLIES]; + int pmugrf_offset; + const char *grf_supply_names[MAX_SUPPLIES]; + const char *pmugrf_supply_names[MAX_SUPPLIES]; void (*init)(struct rockchip_iodomain *iod); }; @@ -64,19 +73,24 @@ struct rockchip_iodomain_supply { struct regulator *reg; struct notifier_block nb; int idx; + enum rockchip_iodomain_grf_type type; }; struct rockchip_iodomain { struct device *dev; struct regmap *grf; + struct regmap *pmu; struct rockchip_iodomain_soc_data *soc_data; - struct rockchip_iodomain_supply supplies[MAX_SUPPLIES]; + struct rockchip_iodomain_supply grf_supplies[MAX_SUPPLIES]; + struct rockchip_iodomain_supply pmugrf_supplies[MAX_SUPPLIES]; }; static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply, int uV) { struct rockchip_iodomain *iod = supply->iod; + struct regmap *reg; + int offset; u32 val; int ret; @@ -87,7 +101,15 @@ static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply, /* apply hiword-mask */ val |= (BIT(supply->idx) << 16); - ret = regmap_write(iod->grf, iod->soc_data->grf_offset, val); + if (supply->type == GRF) { + reg = iod->grf; + offset = iod->soc_data->grf_offset; + } else if (supply->type == PMU_GRF) { + reg = iod->pmu; + offset = iod->soc_data->pmugrf_offset; + } + + ret = regmap_write(reg, offset, val); if (ret) dev_err(iod->dev, "Couldn't write to GRF\n"); @@ -150,7 +172,7 @@ static void rk3288_iodomain_init(struct rockchip_iodomain *iod) u32 val; /* if no flash supply we should leave things alone */ - if (!iod->supplies[RK3288_SOC_FLASH_SUPPLY_NUM].reg) + if (!iod->grf_supplies[RK3288_SOC_FLASH_SUPPLY_NUM].reg) return; /* @@ -169,7 +191,7 @@ static void rk3368_iodomain_init(struct rockchip_iodomain *iod) u32 val; /* if no flash supply we should leave things alone */ - if (!iod->supplies[RK3368_SOC_FLASH_SUPPLY_NUM].reg) + if (!iod->grf_supplies[RK3368_SOC_FLASH_SUPPLY_NUM].reg) return; /* @@ -189,7 +211,7 @@ static void rk3368_iodomain_init(struct rockchip_iodomain *iod) */ static const struct rockchip_iodomain_soc_data soc_data_rk3188 = { .grf_offset = 0x104, - .supply_names = { + .grf_supply_names = { NULL, NULL, NULL, @@ -211,7 +233,7 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3188 = { static const struct rockchip_iodomain_soc_data soc_data_rk3288 = { .grf_offset = 0x380, - .supply_names = { + .grf_supply_names = { "lcdc", /* LCDC_VDD */ "dvp", /* DVPIO_VDD */ "flash0", /* FLASH0_VDD (emmc) */ @@ -228,16 +250,25 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3288 = { static const struct rockchip_iodomain_soc_data soc_data_rk3368 = { .grf_offset = 0x900, - .supply_names = { + .pmugrf_offset = 0x100, + .grf_supply_names = { + NULL, + "dvp", /*DVP IO domain*/ + "flash0", /*FLASH0 IO domain*/ + "wifi", /*APIO2 IO domain*/ + NULL, + "audio", /*APIO3 IO domain*/ + "sdcard", /*SDCARD IO domain*/ + "gpio30", /*APIO1 IO domain*/ + "gpio1830", /*ADIO4 IO domain*/ + }, + .pmugrf_supply_names = { + NULL, + NULL, NULL, - "dvp_v18sel", /*DVP IO domain*/ - "flash0_v18sel", /*FLASH0 IO domain*/ - "wifi_v18sel", /*WIFI IO domain*/ NULL, - "audio_v18sel", /*AUDIO IO domain*/ - "sdcard_v18sel", /*SDCARD IO domain*/ - "gpio30_v18sel", /*GPIO30 IO domain*/ - "gpio1830_v18sel", /*GPIO1830 IO domain*/ + "pmu", /*PMU IO domain*/ + "vop", /*LCDC IO domain*/ }, .init = rk3368_iodomain_init, }; @@ -259,47 +290,34 @@ static const struct of_device_id rockchip_iodomain_match[] = { { /* sentinel */ }, }; -static int rockchip_iodomain_probe(struct platform_device *pdev) +static int rockchip_iodomain_parse_supply(struct rockchip_iodomain *iod, + struct device_node *np, + enum rockchip_iodomain_grf_type type) { - struct device_node *np = pdev->dev.of_node; - const struct of_device_id *match; - struct rockchip_iodomain *iod; + struct rockchip_iodomain_supply *group_supply; + const char **group_supply_names; int i, ret = 0; - if (!np) - return -ENODEV; - - iod = devm_kzalloc(&pdev->dev, sizeof(*iod), GFP_KERNEL); - if (!iod) - return -ENOMEM; - - iod->dev = &pdev->dev; - platform_set_drvdata(pdev, iod); - - match = of_match_node(rockchip_iodomain_match, np); - iod->soc_data = (struct rockchip_iodomain_soc_data *)match->data; - - iod->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); - if (IS_ERR(iod->grf)) { - dev_err(&pdev->dev, "couldn't find grf regmap\n"); - return PTR_ERR(iod->grf); + if (type == GRF) { + group_supply_names = + (const char **)iod->soc_data->grf_supply_names; + group_supply = iod->grf_supplies; + } else if (type == PMU_GRF) { + group_supply_names = + (const char **)iod->soc_data->pmugrf_supply_names; + group_supply = iod->pmugrf_supplies; } for (i = 0; i < MAX_SUPPLIES; i++) { - const char *supply_name = iod->soc_data->supply_names[i]; - struct rockchip_iodomain_supply *supply = &iod->supplies[i]; + const char *supply_name = group_supply_names[i]; + struct rockchip_iodomain_supply *supply = &group_supply[i]; struct regulator *reg; int uV; - const char *regulator_name = NULL; if (!supply_name) continue; - of_property_read_string(np, supply_name, ®ulator_name); - if (!regulator_name) - continue; - - reg = regulator_get(NULL, regulator_name); + reg = devm_regulator_get_optional(iod->dev, supply_name); if (IS_ERR(reg)) { ret = PTR_ERR(reg); @@ -334,6 +352,7 @@ static int rockchip_iodomain_probe(struct platform_device *pdev) supply->idx = i; supply->iod = iod; supply->reg = reg; + supply->type = type; supply->nb.notifier_call = rockchip_iodomain_notify; ret = rockchip_iodomain_write(supply, uV); @@ -345,21 +364,16 @@ static int rockchip_iodomain_probe(struct platform_device *pdev) /* register regulator notifier */ ret = regulator_register_notifier(reg, &supply->nb); if (ret) { - dev_err(&pdev->dev, + dev_err(iod->dev, "regulator notifier request failed\n"); supply->reg = NULL; goto unreg_notify; } } - if (iod->soc_data->init) - iod->soc_data->init(iod); - - return 0; - unreg_notify: for (i = MAX_SUPPLIES - 1; i >= 0; i--) { - struct rockchip_iodomain_supply *io_supply = &iod->supplies[i]; + struct rockchip_iodomain_supply *io_supply = &group_supply[i]; if (io_supply->reg) regulator_unregister_notifier(io_supply->reg, @@ -369,13 +383,75 @@ unreg_notify: return ret; } +static int rockchip_iodomain_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node, *node; + const struct of_device_id *match; + struct rockchip_iodomain *iod; + int ret = 0; + + if (!np) + return -ENODEV; + + iod = devm_kzalloc(&pdev->dev, sizeof(*iod), GFP_KERNEL); + if (!iod) + return -ENOMEM; + + iod->dev = &pdev->dev; + platform_set_drvdata(pdev, iod); + + match = of_match_node(rockchip_iodomain_match, np); + iod->soc_data = (struct rockchip_iodomain_soc_data *)match->data; + + iod->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); + if (IS_ERR(iod->grf)) { + dev_err(&pdev->dev, "couldn't find grf regmap\n"); + return PTR_ERR(iod->grf); + } + ret = rockchip_iodomain_parse_supply(iod, np, GRF); + if (ret) { + dev_err(iod->dev, + "rockchip iodomain parse grf supply failed\n"); + return ret; + } + + /* try to find the optional reference to the pmu syscon */ + node = of_parse_phandle(np, "rockchip,pmu", 0); + if (node) { + iod->pmu = syscon_node_to_regmap(node); + if (IS_ERR(iod->pmu)) + return PTR_ERR(iod->pmu); + ret = rockchip_iodomain_parse_supply(iod, np, PMU_GRF); + if (ret) { + dev_err(iod->dev, + "rockchip iodomain parse pmu_grf supply failed\n"); + return ret; + } + } + + if (iod->soc_data->init) + iod->soc_data->init(iod); + + return ret; +} + static int rockchip_iodomain_remove(struct platform_device *pdev) { struct rockchip_iodomain *iod = platform_get_drvdata(pdev); int i; for (i = MAX_SUPPLIES - 1; i >= 0; i--) { - struct rockchip_iodomain_supply *io_supply = &iod->supplies[i]; + struct rockchip_iodomain_supply *io_supply + = &iod->grf_supplies[i]; + + if (io_supply->reg) + regulator_unregister_notifier(io_supply->reg, + &io_supply->nb); + } + + for (i = MAX_SUPPLIES - 1; i >= 0; i--) { + struct rockchip_iodomain_supply *io_supply = + &iod->pmugrf_supplies[i]; if (io_supply->reg) regulator_unregister_notifier(io_supply->reg,