soc: rockchip: io-domain: rv1126 use separated notify

RV1126 set 3.3V before regulator disable.

Do a fix to rockchip io-domain, follow this orders:

* system running state
  -> io-domain vsel to 3.3V (actually is done by event-disable)
    -> regulator_enable
      -> vsel change according to regulator voltage

* system running state
  -> regulator_disable
    -> io-domain vsel to 3.3V

The bug only instance on RV1126, and tested on RV1126 EVB DDR3 V10.

Change-Id: Ic9d6b05d07b050c392e415786cf6390cc1c5aa9e
Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
This commit is contained in:
Jianqun Xu
2021-08-16 11:06:15 +08:00
committed by Tao Huang
parent 40d4b2db5f
commit 8c65c19483

View File

@@ -610,6 +610,55 @@ static const struct of_device_id rockchip_iodomain_match[] = {
};
MODULE_DEVICE_TABLE(of, rockchip_iodomain_match);
static int rv1126_iodomain_notify(struct notifier_block *nb,
unsigned long event,
void *data)
{
struct rockchip_iodomain_supply *supply =
container_of(nb, struct rockchip_iodomain_supply, nb);
int uV;
int ret;
if (event & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) {
struct pre_voltage_change_data *pvc_data = data;
uV = max_t(unsigned long, pvc_data->old_uV, pvc_data->max_uV);
} else if (event & (REGULATOR_EVENT_VOLTAGE_CHANGE |
REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE)) {
uV = (unsigned long)data;
} else if (event & REGULATOR_EVENT_DISABLE) {
uV = MAX_VOLTAGE_3_3;
} else if (event & REGULATOR_EVENT_ENABLE) {
if (!data)
return NOTIFY_BAD;
uV = (unsigned long)data;
} else {
return NOTIFY_OK;
}
if (uV <= 0) {
dev_err(supply->iod->dev, "Voltage invalid: %d\n", uV);
return NOTIFY_BAD;
}
dev_dbg(supply->iod->dev, "Setting to %d\n", uV);
if (uV > MAX_VOLTAGE_3_3) {
dev_err(supply->iod->dev, "Voltage too high: %d\n", uV);
if (event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
return NOTIFY_BAD;
}
ret = supply->iod->write(supply, uV);
if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
return NOTIFY_BAD;
dev_dbg(supply->iod->dev, "Setting to %d done\n", uV);
return NOTIFY_OK;
}
static int rockchip_iodomain_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -695,6 +744,8 @@ static int rockchip_iodomain_probe(struct platform_device *pdev)
supply->iod = iod;
supply->reg = reg;
supply->nb.notifier_call = rockchip_iodomain_notify;
if (IS_ENABLED(CONFIG_CPU_RV1126))
supply->nb.notifier_call = rv1126_iodomain_notify;
ret = iod->write(supply, uV);
if (ret) {