From d3dd2a1713f37da895218b40724e616c53dd4be4 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Tue, 5 Jan 2021 17:52:00 -0800 Subject: [PATCH 1/7] bus: mhi: host: Prevent warnings on clearing channel context twice Do not allow clearing the channel context twice from mhi_driver_remove(), if already done before disable transition is initiated. This prevents kernel warnings such as "trying to free invalid coherent area" from occurring. Change-Id: I85dec0557a287c9207b56d2b2243d53b6a40ff1c Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index bf672de35131..da9eb79b1561 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * */ @@ -1359,6 +1359,7 @@ static int mhi_driver_remove(struct device *dev) if ((ch_state[dir] == MHI_CH_STATE_ENABLED || ch_state[dir] == MHI_CH_STATE_STOP) && + mhi_chan->ch_state != MHI_CH_STATE_DISABLED && !mhi_chan->offload_ch) mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan); From c5dd45c17ab66e1c50354b3c882574b2350ee3d5 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Mon, 26 Oct 2020 11:02:00 -0700 Subject: [PATCH 2/7] bus: mhi: host: Add fallback image support In case firmware request fails to find firmware at the default location, re-try once with a fallback location. This is done by adding fallback firmware image location in controller structure and firmware request is sent again using fallback location. Send a status call back to controller when re-try is done to notify them as some features may not be available. Change-Id: I6c832c121e7bfaf798c06d0341541a2677653fd0 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/boot.c | 16 ++++++++++++++-- include/linux/mhi.h | 4 ++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 26d0eddb1477..65aa9b9de487 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -435,8 +435,20 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) ret = request_firmware(&firmware, fw_name, dev); if (ret) { - dev_err(dev, "Error loading firmware: %d\n", ret); - goto error_fw_load; + if (!mhi_cntrl->fallback_fw_image) { + dev_err(dev, "Error loading firmware: %d\n", ret); + goto error_fw_load; + } + + ret = request_firmware(&firmware, + mhi_cntrl->fallback_fw_image, + dev); + if (ret) { + dev_err(dev, "Error loading fallback firmware: %d\n", + ret); + goto error_fw_load; + } + mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_FALLBACK_IMG); } size = (mhi_cntrl->fbc_download) ? mhi_cntrl->sbl_size : firmware->size; diff --git a/include/linux/mhi.h b/include/linux/mhi.h index a5441ad33c74..d6208c42f7e8 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -34,6 +34,7 @@ struct mhi_buf_info; * @MHI_CB_SYS_ERROR: MHI device entered error state (may recover) * @MHI_CB_FATAL_ERROR: MHI device entered fatal error state * @MHI_CB_BW_REQ: Received a bandwidth switch request from device + * @MHI_CB_FALLBACK_IMG: MHI device was loaded with the provided fallback image */ enum mhi_callback { MHI_CB_IDLE, @@ -45,6 +46,7 @@ enum mhi_callback { MHI_CB_SYS_ERROR, MHI_CB_FATAL_ERROR, MHI_CB_BW_REQ, + MHI_CB_FALLBACK_IMG, }; /** @@ -299,6 +301,7 @@ struct mhi_controller_config { * @iova_start: IOMMU starting address for data (required) * @iova_stop: IOMMU stop address for data (required) * @fw_image: Firmware image name for normal booting (optional) + * @fallback_fw_image: Fallback firmware image name for backup boot (optional) * @edl_image: Firmware image name for emergency download mode (optional) * @rddm_size: RAM dump size that host should allocate for debugging purpose * @sbl_size: SBL image size downloaded through BHIe (optional) @@ -384,6 +387,7 @@ struct mhi_controller { dma_addr_t iova_start; dma_addr_t iova_stop; const char *fw_image; + const char *fallback_fw_image; const char *edl_image; size_t rddm_size; size_t sbl_size; From 955a4b15ab6172093209c04b6098eb1ece0b8c4a Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Tue, 21 Apr 2020 16:13:00 -0700 Subject: [PATCH 3/7] bus: mhi: host: Add support for event ring processing priorities Default processing priority for an event ring is set to schedule a regular priority tasklet. In order to distinguish going forward and provide support for scheduling a high priority tasklet or any further requirements that may come up, introduce support for different event ring priorities. Change-Id: I53325bc141269832444ba28a4941c050ceebe394 Signed-off-by: Hemant Kumar Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/init.c | 3 +-- drivers/bus/mhi/host/main.c | 19 ++++++++++++++++--- include/linux/mhi.h | 12 +++++++++++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index da9eb79b1561..b5c696a4cb2a 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -687,8 +687,7 @@ static int parse_ev_cfg(struct mhi_controller *mhi_cntrl, &mhi_cntrl->mhi_chan[mhi_event->chan]; } - /* Priority is fixed to 1 for now */ - mhi_event->priority = 1; + mhi_event->priority = event_cfg->priority; mhi_event->db_cfg.brstmode = event_cfg->mode; if (MHI_INVALID_BRSTMODE(mhi_event->db_cfg.brstmode)) diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index f3aef77a6a4a..116f86685851 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -426,10 +426,11 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl) } } -irqreturn_t mhi_irq_handler(int irq_number, void *dev) +irqreturn_t mhi_irq_handler(int irq_number, void *priv) { - struct mhi_event *mhi_event = dev; + struct mhi_event *mhi_event = priv; struct mhi_controller *mhi_cntrl = mhi_event->mhi_cntrl; + struct device *dev = &mhi_cntrl->mhi_dev->dev; struct mhi_event_ctxt *er_ctxt = &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; struct mhi_ring *ev_ring = &mhi_event->ring; @@ -455,8 +456,20 @@ irqreturn_t mhi_irq_handler(int irq_number, void *dev) if (mhi_dev) mhi_notify(mhi_dev, MHI_CB_PENDING_DATA); - } else { + + return IRQ_HANDLED; + } + + switch (mhi_event->priority) { + case MHI_ER_PRIORITY_HI_NOSLEEP: + tasklet_hi_schedule(&mhi_event->task); + break; + case MHI_ER_PRIORITY_DEFAULT_NOSLEEP: tasklet_schedule(&mhi_event->task); + break; + default: + dev_dbg(dev, "skip unknown priority event\n"); + break; } return IRQ_HANDLED; diff --git a/include/linux/mhi.h b/include/linux/mhi.h index d6208c42f7e8..33952bfd76d9 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -191,6 +191,16 @@ enum mhi_er_data_type { MHI_ER_CTRL, }; +/** + * enum mhi_er_priority - Event ring processing priority + * @MHI_ER_PRIORITY_DEFAULT_NOSLEEP: processed by tasklet + * @MHI_ER_PRIORITY_HI_NOSLEEP: processed by hi-priority tasklet + */ +enum mhi_er_priority { + MHI_ER_PRIORITY_DEFAULT_NOSLEEP, + MHI_ER_PRIORITY_HI_NOSLEEP, +}; + /** * enum mhi_db_brst_mode - Doorbell mode * @MHI_DB_BRST_DISABLE: Burst mode disable @@ -244,7 +254,7 @@ struct mhi_channel_config { * @irq_moderation_ms: Delay irq for additional events to be aggregated * @irq: IRQ associated with this ring * @channel: Dedicated channel number. U32_MAX indicates a non-dedicated ring - * @priority: Priority of this ring. Use 1 for now + * @priority: Processing priority of this ring. * @mode: Doorbell mode * @data_type: Type of data this ring will process * @hardware_event: This ring is associated with hardware channels From 975ca1a62c19378543edc4449fe64f8d1b0a2184 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Tue, 5 May 2020 19:44:42 -0700 Subject: [PATCH 4/7] bus: mhi: host: Add helper API to ring event ring doorbells SW event ring elements are added and doorbells are rung during ready state transition from host. HW event ring elements are added and doorbells are rung in mission mode transition. All event ring doorbells are rung in M0 state change transition. Move this common code to a helper API mhi_setup_event_rings(). Pass a boolean for adding event ring elements. When this flag is false, only ring doorbells for all event rings and do not populate the event rings. Change-Id: Ib201007179c2cb772decb2456d3510602ea63fd6 Signed-off-by: Hemant Kumar Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/pm.c | 96 +++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 50 deletions(-) diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index 4a42186ff111..b60021d73efc 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -156,14 +156,52 @@ static void mhi_toggle_dev_wake(struct mhi_controller *mhi_cntrl) mhi_cntrl->wake_put(mhi_cntrl, true); } +/* Add event ring elements and ring er db */ +static void mhi_setup_event_rings(struct mhi_controller *mhi_cntrl, bool add_el) +{ + struct mhi_event *mhi_event; + int i; + bool skip_er_setup; + + mhi_event = mhi_cntrl->mhi_event; + for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { + struct mhi_ring *ring = &mhi_event->ring; + + if (mhi_event->offload_ev) + continue; + + /* skip HW event ring setup in ready state */ + if (mhi_cntrl->dev_state == MHI_STATE_READY) + skip_er_setup = mhi_event->hw_ring; + else + skip_er_setup = !mhi_event->hw_ring; + + /* if no er element to add, ring all er dbs */ + if (add_el && skip_er_setup) + continue; + + if (add_el) { + ring->wp = ring->base + ring->len - ring->el_size; + *ring->ctxt_wp = + ring->iommu_base + ring->len - ring->el_size; + /* Update all cores */ + smp_wmb(); + } + + /* Ring the event ring db */ + spin_lock_irq(&mhi_event->lock); + mhi_ring_er_db(mhi_event); + spin_unlock_irq(&mhi_event->lock); + } +} + /* Handle device ready state transition */ int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl) { - struct mhi_event *mhi_event; enum mhi_pm_state cur_state; struct device *dev = &mhi_cntrl->mhi_dev->dev; u32 interval_us = 25000; /* poll register field every 25 milliseconds */ - int ret, i; + int ret = -EINVAL; /* Check if device entered error state */ if (MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) { @@ -212,25 +250,8 @@ int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl) goto error_mmio; } - /* Add elements to all SW event rings */ - mhi_event = mhi_cntrl->mhi_event; - for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { - struct mhi_ring *ring = &mhi_event->ring; - - /* Skip if this is an offload or HW event */ - if (mhi_event->offload_ev || mhi_event->hw_ring) - continue; - - ring->wp = ring->base + ring->len - ring->el_size; - *ring->ctxt_wp = cpu_to_le64(ring->iommu_base + ring->len - ring->el_size); - /* Update all cores */ - smp_wmb(); - - /* Ring the event ring db */ - spin_lock_irq(&mhi_event->lock); - mhi_ring_er_db(mhi_event); - spin_unlock_irq(&mhi_event->lock); - } + /* add SW event ring elements and ring SW event ring dbs */ + mhi_setup_event_rings(mhi_cntrl, true); /* Set MHI to M0 state */ mhi_set_mhi_state(mhi_cntrl, MHI_STATE_M0); @@ -267,18 +288,10 @@ int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl) /* Ring all event rings and CMD ring only if we're in mission mode */ if (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) { - struct mhi_event *mhi_event = mhi_cntrl->mhi_event; struct mhi_cmd *mhi_cmd = &mhi_cntrl->mhi_cmd[PRIMARY_CMD_RING]; - for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { - if (mhi_event->offload_ev) - continue; - - spin_lock_irq(&mhi_event->lock); - mhi_ring_er_db(mhi_event); - spin_unlock_irq(&mhi_event->lock); - } + mhi_setup_event_rings(mhi_cntrl, false); /* Only ring primary cmd ring if ring is not empty */ spin_lock_irq(&mhi_cmd->lock); @@ -377,10 +390,9 @@ int mhi_pm_m3_transition(struct mhi_controller *mhi_cntrl) /* Handle device Mission Mode transition */ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) { - struct mhi_event *mhi_event; struct device *dev = &mhi_cntrl->mhi_dev->dev; enum mhi_ee_type ee = MHI_EE_MAX, current_ee = mhi_cntrl->ee; - int i, ret; + int ret; dev_dbg(dev, "Processing Mission Mode transition\n"); @@ -415,24 +427,8 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) goto error_mission_mode; } - /* Add elements to all HW event rings */ - mhi_event = mhi_cntrl->mhi_event; - for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { - struct mhi_ring *ring = &mhi_event->ring; - - if (mhi_event->offload_ev || !mhi_event->hw_ring) - continue; - - ring->wp = ring->base + ring->len - ring->el_size; - *ring->ctxt_wp = cpu_to_le64(ring->iommu_base + ring->len - ring->el_size); - /* Update to all cores */ - smp_wmb(); - - spin_lock_irq(&mhi_event->lock); - if (MHI_DB_ACCESS_VALID(mhi_cntrl)) - mhi_ring_er_db(mhi_event); - spin_unlock_irq(&mhi_event->lock); - } + /* Add elements to all HW event rings and ring HW event ring dbs */ + mhi_setup_event_rings(mhi_cntrl, true); read_unlock_bh(&mhi_cntrl->pm_lock); From 85269c6e8836046ee117d55839e2d0f0792f88dc Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 23 Oct 2020 17:51:00 -0700 Subject: [PATCH 5/7] bus: mhi: core: Add support to pre allocate image buffers This allows controller to keep the memory allocated for bhi vector table for rddm and fbc images. Memory remains allocated after controller powers down and is freed when the controller unregisters with MHI. Add a controller flag to make the decision for memory allocation. Change-Id: I974e44d3b927da1003e232455067c50fdf6fb42b Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/boot.c | 24 +++++++++++++++--------- drivers/bus/mhi/host/init.c | 20 ++++++++++---------- drivers/bus/mhi/host/internal.h | 2 +- drivers/bus/mhi/host/pm.c | 2 ++ include/linux/mhi.h | 2 ++ 5 files changed, 30 insertions(+), 20 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 65aa9b9de487..c712a2654aec 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -299,17 +299,22 @@ static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl, } void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl, - struct image_info *image_info) + struct image_info **image_info) { int i; - struct mhi_buf *mhi_buf = image_info->mhi_buf; + struct mhi_buf *mhi_buf = (*image_info)->mhi_buf; - for (i = 0; i < image_info->entries; i++, mhi_buf++) + if (mhi_cntrl->img_pre_alloc) + return; + + for (i = 0; i < (*image_info)->entries; i++, mhi_buf++) dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len, mhi_buf->buf, mhi_buf->dma_addr); - kfree(image_info->mhi_buf); - kfree(image_info); + kfree((*image_info)->mhi_buf); + kfree(*image_info); + + *image_info = NULL; } int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl, @@ -322,6 +327,9 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl, struct image_info *img_info; struct mhi_buf *mhi_buf; + if (mhi_cntrl->img_pre_alloc) + return 0; + img_info = kzalloc(sizeof(*img_info), GFP_KERNEL); if (!img_info) return -ENOMEM; @@ -516,10 +524,8 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) return; error_ready_state: - if (mhi_cntrl->fbc_download) { - mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image); - mhi_cntrl->fbc_image = NULL; - } + if (mhi_cntrl->fbc_download) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image); error_fw_load: mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR; diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index b5c696a4cb2a..6b660d014eea 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -1040,8 +1040,15 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl) unsigned int i; mhi_deinit_free_irq(mhi_cntrl); + /* Free the memory controller wanted to preserve for BHIe images */ + if (mhi_cntrl->img_pre_alloc) { + mhi_cntrl->img_pre_alloc = false; + if (mhi_cntrl->fbc_image) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image); + if (mhi_cntrl->rddm_image) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->rddm_image); + } mhi_destroy_debugfs(mhi_cntrl); - destroy_workqueue(mhi_cntrl->hiprio_wq); kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_event); @@ -1162,15 +1169,8 @@ EXPORT_SYMBOL_GPL(mhi_prepare_for_power_up); void mhi_unprepare_after_power_down(struct mhi_controller *mhi_cntrl) { - if (mhi_cntrl->fbc_image) { - mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image); - mhi_cntrl->fbc_image = NULL; - } - - if (mhi_cntrl->rddm_image) { - mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->rddm_image); - mhi_cntrl->rddm_image = NULL; - } + if (mhi_cntrl->rddm_image) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->rddm_image); mhi_cntrl->bhi = NULL; mhi_cntrl->bhie = NULL; diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index 3d62b836a67c..193a3493627e 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -277,7 +277,7 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl); int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl, struct image_info **image_info, size_t alloc_size); void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl, - struct image_info *image_info); + struct image_info **image_info); /* Power management APIs */ enum mhi_pm_state __must_check mhi_tryset_pm_state( diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index b60021d73efc..cda374bfc9ef 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -1186,6 +1186,8 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) flush_work(&mhi_cntrl->st_worker); disable_irq(mhi_cntrl->irq[0]); + if (mhi_cntrl->fbc_image) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image); } EXPORT_SYMBOL_GPL(mhi_power_down); diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 33952bfd76d9..e251cb6e9407 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -366,6 +366,7 @@ struct mhi_controller_config { * @reset: Controller specific reset function (optional) * @buffer_len: Bounce buffer length * @index: Index of the MHI controller instance + * @img_pre_alloc: allocate rddm and fbc image buffers one time * @bounce_buf: Use of bounce buffer * @fbc_download: MHI host needs to do complete image transfer (optional) * @wake_set: Device wakeup set flag @@ -461,6 +462,7 @@ struct mhi_controller { size_t buffer_len; int index; + bool img_pre_alloc; bool bounce_buf; bool fbc_download; bool wake_set; From 6ff1554291733bb9a7c858dcd4901c9b4fbae5ea Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Thu, 16 Sep 2021 15:39:00 -0700 Subject: [PATCH 6/7] bus: mhi: core: Enable bandwidth scaling usage Enable bandwidth scaling usage for MHI core driver. Change-Id: I31492bd87162c0347f9f8f8acc1a0316a84af572 Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/init.c | 5 +++++ include/linux/mhi.h | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 6b660d014eea..cc31ed191943 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -563,6 +563,8 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl) return ret; } + mhi_misc_init_mmio(mhi_cntrl); + return 0; } @@ -707,6 +709,9 @@ static int parse_ev_cfg(struct mhi_controller *mhi_cntrl, case MHI_ER_CTRL: mhi_event->process_event = mhi_process_ctrl_ev_ring; break; + case MHI_ER_BW_SCALE: + mhi_event->process_event = mhi_process_misc_bw_ev_ring; + break; default: dev_err(dev, "Event Ring type not supported\n"); goto error_ev_cfg; diff --git a/include/linux/mhi.h b/include/linux/mhi.h index e251cb6e9407..cf4029053378 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * */ #ifndef _MHI_H_ @@ -104,10 +104,12 @@ struct image_info { * struct mhi_link_info - BW requirement * target_link_speed - Link speed as defined by TLS bits in LinkControl reg * target_link_width - Link width as defined by NLW bits in LinkStatus reg + * sequence_num - used by device to track bw requests sent to host */ struct mhi_link_info { unsigned int target_link_speed; unsigned int target_link_width; + int sequence_num; }; /** @@ -185,10 +187,12 @@ enum mhi_ch_ee_mask { * enum mhi_er_data_type - Event ring data types * @MHI_ER_DATA: Only client data over this ring * @MHI_ER_CTRL: MHI control data and client data + * @MHI_ER_BW_SCALE: MHI controller bandwidth scale functionality */ enum mhi_er_data_type { MHI_ER_DATA, MHI_ER_CTRL, + MHI_ER_BW_SCALE, }; /** From 93258369b24dffa0465eec60d6fdf4f316445970 Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Thu, 7 May 2020 21:00:41 -0700 Subject: [PATCH 7/7] bus: mhi: host: Move MHI_MAX_MTU to external header file Currently this macro is defined in internal MHI header as a TRE length mask. Moving it to external header allows MHI client drivers to set this upper bound for the transmit buffer size. Change-Id: I24c7bce37cb8f103c1436201d825bec4a36eb122 Signed-off-by: Hemant Kumar Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/internal.h | 1 - include/linux/mhi.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index 193a3493627e..78c33c00393c 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -129,7 +129,6 @@ enum mhi_pm_state { #define CMD_EL_PER_RING 128 #define PRIMARY_CMD_RING 0 #define MHI_DEV_WAKE_DB 127 -#define MHI_MAX_MTU 0xffff #define MHI_RANDOM_U32_NONZERO(bmsk) (prandom_u32_max(bmsk) + 1) enum mhi_er_type { diff --git a/include/linux/mhi.h b/include/linux/mhi.h index cf4029053378..7c182fda4d7c 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -15,6 +15,9 @@ #include #include +/* MHI client drivers to set this upper bound for tx buffer */ +#define MHI_MAX_MTU 0xffff + #define MHI_MAX_OEM_PK_HASH_SEGMENTS 16 struct mhi_chan;