diff --git a/drivers/esoc/esoc-mdm-4x.c b/drivers/esoc/esoc-mdm-4x.c index b9de06cb7bd4..63e216f17654 100644 --- a/drivers/esoc/esoc-mdm-4x.c +++ b/drivers/esoc/esoc-mdm-4x.c @@ -1119,7 +1119,7 @@ static struct mdm_ops sdxprairie_ops = { static struct mdm_ops marmot_ops = { .clink_ops = &mdm_cops, .config_hw = marmot_setup_hw, - .pon_ops = &sdx50m_pon_ops, + .pon_ops = &sdxmarmot_pon_ops, }; static const struct of_device_id mdm_dt_match[] = { diff --git a/drivers/esoc/esoc-mdm-pon.c b/drivers/esoc/esoc-mdm-pon.c index 6e75fb5a4dbd..6470f70332cb 100644 --- a/drivers/esoc/esoc-mdm-pon.c +++ b/drivers/esoc/esoc-mdm-pon.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2015, 2017-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -115,6 +115,44 @@ static int mdm4x_do_first_power_on(struct mdm_ctrl *mdm) return 0; } +static int sdxmarmot_do_first_power_on(struct mdm_ctrl *mdm) +{ + int i; + int pblrdy; + struct device *dev = mdm->dev; + + esoc_mdm_log("Powering on modem for the first time\n"); + dev_dbg(dev, "Powering on modem for the first time\n"); + if (mdm->esoc->auto_boot) + return 0; + + mdm_toggle_soft_reset(mdm, false); + /* Add a delay to allow PON sequence to complete*/ + msleep(325); + esoc_mdm_log("Setting AP2MDM_STATUS = 1\n"); + gpio_direction_output(MDM_GPIO(mdm, AP2MDM_STATUS), 1); + if (gpio_is_valid(MDM_GPIO(mdm, MDM2AP_PBLRDY))) { + for (i = 0; i < MDM_PBLRDY_CNT; i++) { + pblrdy = gpio_get_value(MDM_GPIO(mdm, MDM2AP_PBLRDY)); + if (pblrdy) + break; + usleep_range(5000, 6000); + } + dev_dbg(dev, "pblrdy i:%d\n", i); + msleep(200); + } + /* + * No PBLRDY gpio associated with this modem + * Send request for image. Let userspace confirm establishment of + * link to external modem. + */ + else { + esoc_mdm_log("Queueing the request: ESOC_REQ_IMG\n"); + esoc_clink_queue_request(ESOC_REQ_IMG, mdm->esoc); + } + return 0; +} + static int mdm9x55_power_down(struct mdm_ctrl *mdm) { struct device *dev = mdm->dev; @@ -270,3 +308,12 @@ struct mdm_pon_ops sdx50m_pon_ops = { .dt_init = mdm4x_pon_dt_init, .setup = mdm4x_pon_setup, }; + +struct mdm_pon_ops sdxmarmot_pon_ops = { + .pon = sdxmarmot_do_first_power_on, + .soft_reset = sdx50m_toggle_soft_reset, + .poff_force = sdx50m_power_down, + .cold_reset = sdx50m_cold_reset, + .dt_init = mdm4x_pon_dt_init, + .setup = mdm4x_pon_setup, +}; diff --git a/drivers/esoc/esoc-mdm.h b/drivers/esoc/esoc-mdm.h index 5f6a5d8b4aa2..e1246c3b5cab 100644 --- a/drivers/esoc/esoc-mdm.h +++ b/drivers/esoc/esoc-mdm.h @@ -155,4 +155,5 @@ static inline int mdm_pon_setup(struct mdm_ctrl *mdm) extern struct mdm_pon_ops mdm9x55_pon_ops; extern struct mdm_pon_ops sdx50m_pon_ops; +extern struct mdm_pon_ops sdxmarmot_pon_ops; #endif