diff mbox series

[v2,8/8] bus: mhi: ep: wake up host is the MHI state is in M3

Message ID 1688122331-25478-9-git-send-email-quic_krichai@quicinc.com
State New
Headers show
Series PCCI: EPC: Add support to wake up host from D3 states | expand

Commit Message

Krishna chaitanya chundru June 30, 2023, 10:52 a.m. UTC
If the MHI state is in M3 then the most probably the host kept the
device in D3 hot or D3 cold, due to that endpoint transctions will not
be read by the host, so endpoint needs to bring the host to D0 which
eventually bring back the MHI state to M0.

Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
---
 drivers/bus/mhi/ep/main.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

Comments

Manivannan Sadhasivam July 7, 2023, 6:20 a.m. UTC | #1
On Fri, Jun 30, 2023 at 04:22:11PM +0530, Krishna chaitanya chundru wrote:
> If the MHI state is in M3 then the most probably the host kept the
> device in D3 hot or D3 cold, due to that endpoint transctions will not
> be read by the host, so endpoint needs to bring the host to D0 which
> eventually bring back the MHI state to M0.
> 

Endpoint cannot bring the host to D0, it can only wake up the host and the host
will bring the device to D0.

> Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
> ---
>  drivers/bus/mhi/ep/main.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
> index 6008818..42d3791 100644
> --- a/drivers/bus/mhi/ep/main.c
> +++ b/drivers/bus/mhi/ep/main.c
> @@ -451,12 +451,14 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
>  	struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl;
>  	struct mhi_ep_chan *mhi_chan = mhi_dev->dl_chan;
>  	struct device *dev = &mhi_chan->mhi_dev->dev;
> +	u32 buf_left, read_offset, count = 0;
>  	struct mhi_ring_element *el;
> -	u32 buf_left, read_offset;
>  	struct mhi_ep_ring *ring;
>  	enum mhi_ev_ccs code;
> +	enum mhi_state state;
>  	void *read_addr;
>  	u64 write_addr;
> +	bool mhi_reset;
>  	size_t tr_len;
>  	u32 tre_len;
>  	int ret;
> @@ -464,6 +466,18 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
>  	buf_left = skb->len;
>  	ring = &mhi_cntrl->mhi_chan[mhi_chan->chan].ring;
>  
> +	if (mhi_cntrl->mhi_state == MHI_STATE_M3) {
> +		dev_dbg(dev, "wake up by ch id %x\n", mhi_chan->chan);

This is not needed.

> +		mhi_cntrl->wakeup_host(mhi_cntrl);
> +	}
> +
> +	/* Wait for Host to set the M0 state */
> +	do {
> +		msleep(M0_WAIT_DELAY_MS);
> +		mhi_ep_mmio_get_mhi_state(mhi_cntrl, &state, &mhi_reset);
> +		count++;
> +	} while (state != MHI_STATE_M0 && count < M0_WAIT_COUNT);
> +

Move this change to a function like mhi_ep_wake_host().

- Mani

>  	mutex_lock(&mhi_chan->lock);
>  
>  	do {
> -- 
> 2.7.4
>
Krishna chaitanya chundru July 7, 2023, 11:01 a.m. UTC | #2
On 7/7/2023 11:50 AM, Manivannan Sadhasivam wrote:
> On Fri, Jun 30, 2023 at 04:22:11PM +0530, Krishna chaitanya chundru wrote:
>> If the MHI state is in M3 then the most probably the host kept the
>> device in D3 hot or D3 cold, due to that endpoint transctions will not
>> be read by the host, so endpoint needs to bring the host to D0 which
>> eventually bring back the MHI state to M0.
>>
> Endpoint cannot bring the host to D0, it can only wake up the host and the host
> will bring the device to D0.
>
>> Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
>> ---
>>   drivers/bus/mhi/ep/main.c | 16 +++++++++++++++-
>>   1 file changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
>> index 6008818..42d3791 100644
>> --- a/drivers/bus/mhi/ep/main.c
>> +++ b/drivers/bus/mhi/ep/main.c
>> @@ -451,12 +451,14 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
>>   	struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl;
>>   	struct mhi_ep_chan *mhi_chan = mhi_dev->dl_chan;
>>   	struct device *dev = &mhi_chan->mhi_dev->dev;
>> +	u32 buf_left, read_offset, count = 0;
>>   	struct mhi_ring_element *el;
>> -	u32 buf_left, read_offset;
>>   	struct mhi_ep_ring *ring;
>>   	enum mhi_ev_ccs code;
>> +	enum mhi_state state;
>>   	void *read_addr;
>>   	u64 write_addr;
>> +	bool mhi_reset;
>>   	size_t tr_len;
>>   	u32 tre_len;
>>   	int ret;
>> @@ -464,6 +466,18 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
>>   	buf_left = skb->len;
>>   	ring = &mhi_cntrl->mhi_chan[mhi_chan->chan].ring;
>>   
>> +	if (mhi_cntrl->mhi_state == MHI_STATE_M3) {
>> +		dev_dbg(dev, "wake up by ch id %x\n", mhi_chan->chan);
> This is not needed.
>
>> +		mhi_cntrl->wakeup_host(mhi_cntrl);
>> +	}
>> +
>> +	/* Wait for Host to set the M0 state */
>> +	do {
>> +		msleep(M0_WAIT_DELAY_MS);
>> +		mhi_ep_mmio_get_mhi_state(mhi_cntrl, &state, &mhi_reset);
>> +		count++;
>> +	} while (state != MHI_STATE_M0 && count < M0_WAIT_COUNT);
>> +
> Move this change to a function like mhi_ep_wake_host().
>
> - Mani

Sure I will change it in next patch.

- KC

>
>>   	mutex_lock(&mhi_chan->lock);
>>   
>>   	do {
>> -- 
>> 2.7.4
>>
diff mbox series

Patch

diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
index 6008818..42d3791 100644
--- a/drivers/bus/mhi/ep/main.c
+++ b/drivers/bus/mhi/ep/main.c
@@ -451,12 +451,14 @@  int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
 	struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl;
 	struct mhi_ep_chan *mhi_chan = mhi_dev->dl_chan;
 	struct device *dev = &mhi_chan->mhi_dev->dev;
+	u32 buf_left, read_offset, count = 0;
 	struct mhi_ring_element *el;
-	u32 buf_left, read_offset;
 	struct mhi_ep_ring *ring;
 	enum mhi_ev_ccs code;
+	enum mhi_state state;
 	void *read_addr;
 	u64 write_addr;
+	bool mhi_reset;
 	size_t tr_len;
 	u32 tre_len;
 	int ret;
@@ -464,6 +466,18 @@  int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
 	buf_left = skb->len;
 	ring = &mhi_cntrl->mhi_chan[mhi_chan->chan].ring;
 
+	if (mhi_cntrl->mhi_state == MHI_STATE_M3) {
+		dev_dbg(dev, "wake up by ch id %x\n", mhi_chan->chan);
+		mhi_cntrl->wakeup_host(mhi_cntrl);
+	}
+
+	/* Wait for Host to set the M0 state */
+	do {
+		msleep(M0_WAIT_DELAY_MS);
+		mhi_ep_mmio_get_mhi_state(mhi_cntrl, &state, &mhi_reset);
+		count++;
+	} while (state != MHI_STATE_M0 && count < M0_WAIT_COUNT);
+
 	mutex_lock(&mhi_chan->lock);
 
 	do {