Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-26 Thread CK Hu
On Fri, 2016-06-24 at 19:39 +0800, Horng-Shyang Liao wrote:
> On Tue, 2016-06-21 at 15:46 +0800, Horng-Shyang Liao wrote:
> > On Tue, 2016-06-21 at 10:03 +0800, CK Hu wrote:
> > > On Mon, 2016-06-20 at 19:22 +0800, Horng-Shyang Liao wrote:
> > > > On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> > > > > [Snip...]
> > > > > 
> > > > > > +
> > > > > > +static int cmdq_eng_get_thread(u64 flag)
> > > > > > +{
> > > > > > +   if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > > > > > +   return CMDQ_THR_DISP_MAIN_IDX;
> > > > > > +   else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > > > > > +   return CMDQ_THR_DISP_SUB_IDX;
> > > > > > +   else
> > > > > > +   return CMDQ_THR_DISP_MISC_IDX;
> > > > > > +}
> > > > > 
> > > > > I think cmdq should not have knowledge of client. These statement show
> > > > > that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> > > > > the 'session' to replace engine flag. For example, main display create
> > > > > one cmdq_session and external display create another cmdq_session. For
> > > > > client driver, every tasks created by main display is bound to main
> > > > > display session. For cmdq driver, it should dynamically bind a session
> > > > > to a HW thread, and then dispatch tasks of this session to this HW
> > > > > thread. After HW thread run out of tasks of this session, detach this
> > > > > session with this thread.
> > > > > For the problem of remove wfe cmd, I think a session can have a 
> > > > > property
> > > > > of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> > > > > For other client, it's false.
> > > > 
> > > > Hi CK,
> > > > 
> > > > I think your suggestion is similar to CMDQ 'scenarios',
> > > > which was removed from CMDQ v2.
> > > > 
> > > > Daniel suggests to use engine flags instead of scenarios.
> > > > Quote from https://patchwork.kernel.org/patch/8068311/ .
> > > > 'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
> > > >  cmdq driver should just provide these flag bits, and the display
> > > >  subsystem can use them to build the "flag" parameter itself.
> > > > 
> > > >  After all, the exact configuration of mmsys components is somewhat
> > > >  flexible.'
> > > > 
> > > > Therefore, it would be better to discuss with Daniel before we change
> > > > it.
> > > > 
> > > > 
> > > > Hi Daniel,
> > > > 
> > > > Do you think we should use scenarios or sessions instead of flags?
> > > > 
> > > > Thanks,
> > > > HS
> > > > 
> > > 
> > > Hi, HS:
> > > 
> > > 'session' is not similar to 'scenarios'.
> > > 
> > > In 'scenarios' mechanism, client bind a task with scenarios and send to
> > > cmdq. Cmdq transfer scenarios to engine flag, and use engine flag to
> > > dispatch task to HW thread.
> > > 
> > > 
> > > In 'engine flag' mechanism, proposed by Daniel, client bind a task
> > > directly with engine flag. Cmdq directly use engine flag to dispatch
> > > task to HW thread without any translation.
> > > 
> > > But neither 'scenarios' mechanism nor 'engine flag' mechanism get rid of
> > > engine flag, which make cmdq have knowledge of client.
> > > 
> > > In 'session' mechanism, there is no engine flag any more. Client bind
> > > time-sequential tasks to the same session and tasks in different session
> > > can execute parallelly. One thing cmdq need to know is to dispatch tasks
> > > with the same session to the same HW thread, so cmdq does not have any
> > > knowledge of client.
> > > 
> > > Daniel focus on reduce translating scenarios to engine flag. I think
> > > 'session' mechanism does not conflict with his opinion because we does
> > > not translate 'session' to engine flag. Therefore, I think 'session' is
> > > the best of these three mechanism.
> > > 
> > > Regards,
> > > CK
> > 
> > Hi CK,
> > 
> > 'Session' looks like a group of options for CMDQ.
> > CMDQ driver can just follow the options to run its flow,
> > and doesn't need to know its client(s).
> > 
> > We don't have many options now, but it has good flexibility to extend
> > for future requirements.
> > 
> > I will add it in next version.
> > 
> > Thanks,
> > HS
> 
> Hi CK,
> 
> I think session is very similar to mailbox channel.
> We can treat session's parameters as channel's arguments in device tree.
> Linking session to GCE thread is also just like linking channel to GCE
> thread.
> Because I will use mailbox framework in CMDQ v9, we can use mailbox
> channel instead of session.
> What do you think?
> 
> Thanks,
> HS
> 

Hi, HS:

I'm not familiar with mailbox, but this sounds good to me.

Regards,
CK

> > > > > Here is the sample code to create cmdq_rec with session.
> > > > > 
> > > > > merge_wfe_cmd = true;
> > > > > cmdq_session_create(merge_wfe_cmd, _display_session);
> > > > > cmdq_rec_create(dev, primary_display_session, );
> > > > > 
> > > > > 
> > > > > Therefore, the below definition can be removed.
> > > > > 
> > > > > > +
> > > > > > +enum cmdq_eng {
> > > > > > +   CMDQ_ENG_DISP_AAL,
> > > > > > + 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-26 Thread CK Hu
On Fri, 2016-06-24 at 19:39 +0800, Horng-Shyang Liao wrote:
> On Tue, 2016-06-21 at 15:46 +0800, Horng-Shyang Liao wrote:
> > On Tue, 2016-06-21 at 10:03 +0800, CK Hu wrote:
> > > On Mon, 2016-06-20 at 19:22 +0800, Horng-Shyang Liao wrote:
> > > > On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> > > > > [Snip...]
> > > > > 
> > > > > > +
> > > > > > +static int cmdq_eng_get_thread(u64 flag)
> > > > > > +{
> > > > > > +   if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > > > > > +   return CMDQ_THR_DISP_MAIN_IDX;
> > > > > > +   else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > > > > > +   return CMDQ_THR_DISP_SUB_IDX;
> > > > > > +   else
> > > > > > +   return CMDQ_THR_DISP_MISC_IDX;
> > > > > > +}
> > > > > 
> > > > > I think cmdq should not have knowledge of client. These statement show
> > > > > that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> > > > > the 'session' to replace engine flag. For example, main display create
> > > > > one cmdq_session and external display create another cmdq_session. For
> > > > > client driver, every tasks created by main display is bound to main
> > > > > display session. For cmdq driver, it should dynamically bind a session
> > > > > to a HW thread, and then dispatch tasks of this session to this HW
> > > > > thread. After HW thread run out of tasks of this session, detach this
> > > > > session with this thread.
> > > > > For the problem of remove wfe cmd, I think a session can have a 
> > > > > property
> > > > > of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> > > > > For other client, it's false.
> > > > 
> > > > Hi CK,
> > > > 
> > > > I think your suggestion is similar to CMDQ 'scenarios',
> > > > which was removed from CMDQ v2.
> > > > 
> > > > Daniel suggests to use engine flags instead of scenarios.
> > > > Quote from https://patchwork.kernel.org/patch/8068311/ .
> > > > 'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
> > > >  cmdq driver should just provide these flag bits, and the display
> > > >  subsystem can use them to build the "flag" parameter itself.
> > > > 
> > > >  After all, the exact configuration of mmsys components is somewhat
> > > >  flexible.'
> > > > 
> > > > Therefore, it would be better to discuss with Daniel before we change
> > > > it.
> > > > 
> > > > 
> > > > Hi Daniel,
> > > > 
> > > > Do you think we should use scenarios or sessions instead of flags?
> > > > 
> > > > Thanks,
> > > > HS
> > > > 
> > > 
> > > Hi, HS:
> > > 
> > > 'session' is not similar to 'scenarios'.
> > > 
> > > In 'scenarios' mechanism, client bind a task with scenarios and send to
> > > cmdq. Cmdq transfer scenarios to engine flag, and use engine flag to
> > > dispatch task to HW thread.
> > > 
> > > 
> > > In 'engine flag' mechanism, proposed by Daniel, client bind a task
> > > directly with engine flag. Cmdq directly use engine flag to dispatch
> > > task to HW thread without any translation.
> > > 
> > > But neither 'scenarios' mechanism nor 'engine flag' mechanism get rid of
> > > engine flag, which make cmdq have knowledge of client.
> > > 
> > > In 'session' mechanism, there is no engine flag any more. Client bind
> > > time-sequential tasks to the same session and tasks in different session
> > > can execute parallelly. One thing cmdq need to know is to dispatch tasks
> > > with the same session to the same HW thread, so cmdq does not have any
> > > knowledge of client.
> > > 
> > > Daniel focus on reduce translating scenarios to engine flag. I think
> > > 'session' mechanism does not conflict with his opinion because we does
> > > not translate 'session' to engine flag. Therefore, I think 'session' is
> > > the best of these three mechanism.
> > > 
> > > Regards,
> > > CK
> > 
> > Hi CK,
> > 
> > 'Session' looks like a group of options for CMDQ.
> > CMDQ driver can just follow the options to run its flow,
> > and doesn't need to know its client(s).
> > 
> > We don't have many options now, but it has good flexibility to extend
> > for future requirements.
> > 
> > I will add it in next version.
> > 
> > Thanks,
> > HS
> 
> Hi CK,
> 
> I think session is very similar to mailbox channel.
> We can treat session's parameters as channel's arguments in device tree.
> Linking session to GCE thread is also just like linking channel to GCE
> thread.
> Because I will use mailbox framework in CMDQ v9, we can use mailbox
> channel instead of session.
> What do you think?
> 
> Thanks,
> HS
> 

Hi, HS:

I'm not familiar with mailbox, but this sounds good to me.

Regards,
CK

> > > > > Here is the sample code to create cmdq_rec with session.
> > > > > 
> > > > > merge_wfe_cmd = true;
> > > > > cmdq_session_create(merge_wfe_cmd, _display_session);
> > > > > cmdq_rec_create(dev, primary_display_session, );
> > > > > 
> > > > > 
> > > > > Therefore, the below definition can be removed.
> > > > > 
> > > > > > +
> > > > > > +enum cmdq_eng {
> > > > > > +   CMDQ_ENG_DISP_AAL,
> > > > > > + 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-24 Thread Horng-Shyang Liao
On Tue, 2016-06-21 at 15:46 +0800, Horng-Shyang Liao wrote:
> On Tue, 2016-06-21 at 10:03 +0800, CK Hu wrote:
> > On Mon, 2016-06-20 at 19:22 +0800, Horng-Shyang Liao wrote:
> > > On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> > > > [Snip...]
> > > > 
> > > > > +
> > > > > +static int cmdq_eng_get_thread(u64 flag)
> > > > > +{
> > > > > + if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > > > > + return CMDQ_THR_DISP_MAIN_IDX;
> > > > > + else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > > > > + return CMDQ_THR_DISP_SUB_IDX;
> > > > > + else
> > > > > + return CMDQ_THR_DISP_MISC_IDX;
> > > > > +}
> > > > 
> > > > I think cmdq should not have knowledge of client. These statement show
> > > > that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> > > > the 'session' to replace engine flag. For example, main display create
> > > > one cmdq_session and external display create another cmdq_session. For
> > > > client driver, every tasks created by main display is bound to main
> > > > display session. For cmdq driver, it should dynamically bind a session
> > > > to a HW thread, and then dispatch tasks of this session to this HW
> > > > thread. After HW thread run out of tasks of this session, detach this
> > > > session with this thread.
> > > > For the problem of remove wfe cmd, I think a session can have a property
> > > > of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> > > > For other client, it's false.
> > > 
> > > Hi CK,
> > > 
> > > I think your suggestion is similar to CMDQ 'scenarios',
> > > which was removed from CMDQ v2.
> > > 
> > > Daniel suggests to use engine flags instead of scenarios.
> > > Quote from https://patchwork.kernel.org/patch/8068311/ .
> > > 'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
> > >  cmdq driver should just provide these flag bits, and the display
> > >  subsystem can use them to build the "flag" parameter itself.
> > > 
> > >  After all, the exact configuration of mmsys components is somewhat
> > >  flexible.'
> > > 
> > > Therefore, it would be better to discuss with Daniel before we change
> > > it.
> > > 
> > > 
> > > Hi Daniel,
> > > 
> > > Do you think we should use scenarios or sessions instead of flags?
> > > 
> > > Thanks,
> > > HS
> > > 
> > 
> > Hi, HS:
> > 
> > 'session' is not similar to 'scenarios'.
> > 
> > In 'scenarios' mechanism, client bind a task with scenarios and send to
> > cmdq. Cmdq transfer scenarios to engine flag, and use engine flag to
> > dispatch task to HW thread.
> > 
> > 
> > In 'engine flag' mechanism, proposed by Daniel, client bind a task
> > directly with engine flag. Cmdq directly use engine flag to dispatch
> > task to HW thread without any translation.
> > 
> > But neither 'scenarios' mechanism nor 'engine flag' mechanism get rid of
> > engine flag, which make cmdq have knowledge of client.
> > 
> > In 'session' mechanism, there is no engine flag any more. Client bind
> > time-sequential tasks to the same session and tasks in different session
> > can execute parallelly. One thing cmdq need to know is to dispatch tasks
> > with the same session to the same HW thread, so cmdq does not have any
> > knowledge of client.
> > 
> > Daniel focus on reduce translating scenarios to engine flag. I think
> > 'session' mechanism does not conflict with his opinion because we does
> > not translate 'session' to engine flag. Therefore, I think 'session' is
> > the best of these three mechanism.
> > 
> > Regards,
> > CK
> 
> Hi CK,
> 
> 'Session' looks like a group of options for CMDQ.
> CMDQ driver can just follow the options to run its flow,
> and doesn't need to know its client(s).
> 
> We don't have many options now, but it has good flexibility to extend
> for future requirements.
> 
> I will add it in next version.
> 
> Thanks,
> HS

Hi CK,

I think session is very similar to mailbox channel.
We can treat session's parameters as channel's arguments in device tree.
Linking session to GCE thread is also just like linking channel to GCE
thread.
Because I will use mailbox framework in CMDQ v9, we can use mailbox
channel instead of session.
What do you think?

Thanks,
HS

> > > > Here is the sample code to create cmdq_rec with session.
> > > > 
> > > > merge_wfe_cmd = true;
> > > > cmdq_session_create(merge_wfe_cmd, _display_session);
> > > > cmdq_rec_create(dev, primary_display_session, );
> > > > 
> > > > 
> > > > Therefore, the below definition can be removed.
> > > > 
> > > > > +
> > > > > +enum cmdq_eng {
> > > > > + CMDQ_ENG_DISP_AAL,
> > > > > + CMDQ_ENG_DISP_COLOR0,
> > > > > + CMDQ_ENG_DISP_COLOR1,
> > > > > + CMDQ_ENG_DISP_DPI0,
> > > > > + CMDQ_ENG_DISP_DSI0,
> > > > > + CMDQ_ENG_DISP_DSI1,
> > > > > + CMDQ_ENG_DISP_GAMMA,
> > > > > + CMDQ_ENG_DISP_OD,
> > > > > + CMDQ_ENG_DISP_OVL0,
> > > > > + CMDQ_ENG_DISP_OVL1,
> > > > > + CMDQ_ENG_DISP_PWM0,
> > > > > + CMDQ_ENG_DISP_PWM1,
> > 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-24 Thread Horng-Shyang Liao
On Tue, 2016-06-21 at 15:46 +0800, Horng-Shyang Liao wrote:
> On Tue, 2016-06-21 at 10:03 +0800, CK Hu wrote:
> > On Mon, 2016-06-20 at 19:22 +0800, Horng-Shyang Liao wrote:
> > > On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> > > > [Snip...]
> > > > 
> > > > > +
> > > > > +static int cmdq_eng_get_thread(u64 flag)
> > > > > +{
> > > > > + if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > > > > + return CMDQ_THR_DISP_MAIN_IDX;
> > > > > + else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > > > > + return CMDQ_THR_DISP_SUB_IDX;
> > > > > + else
> > > > > + return CMDQ_THR_DISP_MISC_IDX;
> > > > > +}
> > > > 
> > > > I think cmdq should not have knowledge of client. These statement show
> > > > that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> > > > the 'session' to replace engine flag. For example, main display create
> > > > one cmdq_session and external display create another cmdq_session. For
> > > > client driver, every tasks created by main display is bound to main
> > > > display session. For cmdq driver, it should dynamically bind a session
> > > > to a HW thread, and then dispatch tasks of this session to this HW
> > > > thread. After HW thread run out of tasks of this session, detach this
> > > > session with this thread.
> > > > For the problem of remove wfe cmd, I think a session can have a property
> > > > of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> > > > For other client, it's false.
> > > 
> > > Hi CK,
> > > 
> > > I think your suggestion is similar to CMDQ 'scenarios',
> > > which was removed from CMDQ v2.
> > > 
> > > Daniel suggests to use engine flags instead of scenarios.
> > > Quote from https://patchwork.kernel.org/patch/8068311/ .
> > > 'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
> > >  cmdq driver should just provide these flag bits, and the display
> > >  subsystem can use them to build the "flag" parameter itself.
> > > 
> > >  After all, the exact configuration of mmsys components is somewhat
> > >  flexible.'
> > > 
> > > Therefore, it would be better to discuss with Daniel before we change
> > > it.
> > > 
> > > 
> > > Hi Daniel,
> > > 
> > > Do you think we should use scenarios or sessions instead of flags?
> > > 
> > > Thanks,
> > > HS
> > > 
> > 
> > Hi, HS:
> > 
> > 'session' is not similar to 'scenarios'.
> > 
> > In 'scenarios' mechanism, client bind a task with scenarios and send to
> > cmdq. Cmdq transfer scenarios to engine flag, and use engine flag to
> > dispatch task to HW thread.
> > 
> > 
> > In 'engine flag' mechanism, proposed by Daniel, client bind a task
> > directly with engine flag. Cmdq directly use engine flag to dispatch
> > task to HW thread without any translation.
> > 
> > But neither 'scenarios' mechanism nor 'engine flag' mechanism get rid of
> > engine flag, which make cmdq have knowledge of client.
> > 
> > In 'session' mechanism, there is no engine flag any more. Client bind
> > time-sequential tasks to the same session and tasks in different session
> > can execute parallelly. One thing cmdq need to know is to dispatch tasks
> > with the same session to the same HW thread, so cmdq does not have any
> > knowledge of client.
> > 
> > Daniel focus on reduce translating scenarios to engine flag. I think
> > 'session' mechanism does not conflict with his opinion because we does
> > not translate 'session' to engine flag. Therefore, I think 'session' is
> > the best of these three mechanism.
> > 
> > Regards,
> > CK
> 
> Hi CK,
> 
> 'Session' looks like a group of options for CMDQ.
> CMDQ driver can just follow the options to run its flow,
> and doesn't need to know its client(s).
> 
> We don't have many options now, but it has good flexibility to extend
> for future requirements.
> 
> I will add it in next version.
> 
> Thanks,
> HS

Hi CK,

I think session is very similar to mailbox channel.
We can treat session's parameters as channel's arguments in device tree.
Linking session to GCE thread is also just like linking channel to GCE
thread.
Because I will use mailbox framework in CMDQ v9, we can use mailbox
channel instead of session.
What do you think?

Thanks,
HS

> > > > Here is the sample code to create cmdq_rec with session.
> > > > 
> > > > merge_wfe_cmd = true;
> > > > cmdq_session_create(merge_wfe_cmd, _display_session);
> > > > cmdq_rec_create(dev, primary_display_session, );
> > > > 
> > > > 
> > > > Therefore, the below definition can be removed.
> > > > 
> > > > > +
> > > > > +enum cmdq_eng {
> > > > > + CMDQ_ENG_DISP_AAL,
> > > > > + CMDQ_ENG_DISP_COLOR0,
> > > > > + CMDQ_ENG_DISP_COLOR1,
> > > > > + CMDQ_ENG_DISP_DPI0,
> > > > > + CMDQ_ENG_DISP_DSI0,
> > > > > + CMDQ_ENG_DISP_DSI1,
> > > > > + CMDQ_ENG_DISP_GAMMA,
> > > > > + CMDQ_ENG_DISP_OD,
> > > > > + CMDQ_ENG_DISP_OVL0,
> > > > > + CMDQ_ENG_DISP_OVL1,
> > > > > + CMDQ_ENG_DISP_PWM0,
> > > > > + CMDQ_ENG_DISP_PWM1,
> > 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-23 Thread CK Hu
On Thu, 2016-06-23 at 15:54 +0800, Horng-Shyang Liao wrote:
> Hi CK,
> 
> On Thu, 2016-06-23 at 14:03 +0800, CK Hu wrote:
> > Hi, HS:
> > 
> > On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> > [...]
> > 
> > > +
> > > +/* events for CMDQ and display */
> > > +enum cmdq_event {
> > > + /* Display start of frame(SOF) events */
> > > + CMDQ_EVENT_DISP_OVL0_SOF = 11,
> > > + CMDQ_EVENT_DISP_OVL1_SOF = 12,
> > > + CMDQ_EVENT_DISP_RDMA0_SOF = 13,
> > > + CMDQ_EVENT_DISP_RDMA1_SOF = 14,
> > > + CMDQ_EVENT_DISP_RDMA2_SOF = 15,
> > > + CMDQ_EVENT_DISP_WDMA0_SOF = 16,
> > > + CMDQ_EVENT_DISP_WDMA1_SOF = 17,
> > > + /* Display end of frame(EOF) events */
> > > + CMDQ_EVENT_DISP_OVL0_EOF = 39,
> > > + CMDQ_EVENT_DISP_OVL1_EOF = 40,
> > > + CMDQ_EVENT_DISP_RDMA0_EOF = 41,
> > > + CMDQ_EVENT_DISP_RDMA1_EOF = 42,
> > > + CMDQ_EVENT_DISP_RDMA2_EOF = 43,
> > > + CMDQ_EVENT_DISP_WDMA0_EOF = 44,
> > > + CMDQ_EVENT_DISP_WDMA1_EOF = 45,
> > > + /* Mutex end of frame(EOF) events */
> > > + CMDQ_EVENT_MUTEX0_STREAM_EOF = 53,
> > > + CMDQ_EVENT_MUTEX1_STREAM_EOF = 54,
> > > + CMDQ_EVENT_MUTEX2_STREAM_EOF = 55,
> > > + CMDQ_EVENT_MUTEX3_STREAM_EOF = 56,
> > > + CMDQ_EVENT_MUTEX4_STREAM_EOF = 57,
> > > + /* Display underrun events */
> > > + CMDQ_EVENT_DISP_RDMA0_UNDERRUN = 63,
> > > + CMDQ_EVENT_DISP_RDMA1_UNDERRUN = 64,
> > > + CMDQ_EVENT_DISP_RDMA2_UNDERRUN = 65,
> > > + /* Keep this at the end of HW events */
> > > + CMDQ_MAX_HW_EVENT_COUNT = 260,
> > > +};
> > 
> > The value of these symbol is just the GCE-HW-defined value. I think it's
> > not appropriate to expose HW-defined value to client. For another SoC
> > GCE HW, these definition may change.
> 
> Agree.
> 
> > One way to solve this problem is to translate symbol to value
> > internally. But these events looks like interrupt and the value may vary
> > by each SoC, to prevent driver modified frequently, it's better to place
> > the value definition in device tree. It may looks like:
> > 
> > mmsys: clock-controller@1400 {
> > compatible = "mediatek,mt8173-mmsys";
> > mediatek,gce = <>;
> > gce-events = <53 54>;
> 
> However, client still needs to know the HW-defined value by using
> this solution.
> 
> > gce-event-names = "MUTEX0_EOF","MUTEX1_EOF";
> > }
> > 
> > For cmdq driver, you just need modify interface from
> > 
> > int cmdq_rec_wfe(struct cmdq_rec *rec, enum cmdq_event event)
> > int cmdq_rec_clear_event(struct cmdq_rec *rec, enum cmdq_event event)
> > 
> > to
> > 
> > int cmdq_rec_wfe(struct cmdq_rec *rec, u32 event)
> > int cmdq_rec_clear_event(struct cmdq_rec *rec, u32 event)
> 
> I think an easy way for this issue is just removing HW-defined values
> from include/soc/mediatek/cmdq.h (but keeping enum), and then mapping
> abstract values into real values in driver.
> The benefit of this solution is that we can keep interface and leave SoC
> specific code into driver.
> What do you think?

Hi, HS:

OK, that's fine.

Regards,
CK

> 
> > Regards,
> > CK
> 
> Thanks,
> HS
> 
> 




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-23 Thread CK Hu
On Thu, 2016-06-23 at 15:54 +0800, Horng-Shyang Liao wrote:
> Hi CK,
> 
> On Thu, 2016-06-23 at 14:03 +0800, CK Hu wrote:
> > Hi, HS:
> > 
> > On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> > [...]
> > 
> > > +
> > > +/* events for CMDQ and display */
> > > +enum cmdq_event {
> > > + /* Display start of frame(SOF) events */
> > > + CMDQ_EVENT_DISP_OVL0_SOF = 11,
> > > + CMDQ_EVENT_DISP_OVL1_SOF = 12,
> > > + CMDQ_EVENT_DISP_RDMA0_SOF = 13,
> > > + CMDQ_EVENT_DISP_RDMA1_SOF = 14,
> > > + CMDQ_EVENT_DISP_RDMA2_SOF = 15,
> > > + CMDQ_EVENT_DISP_WDMA0_SOF = 16,
> > > + CMDQ_EVENT_DISP_WDMA1_SOF = 17,
> > > + /* Display end of frame(EOF) events */
> > > + CMDQ_EVENT_DISP_OVL0_EOF = 39,
> > > + CMDQ_EVENT_DISP_OVL1_EOF = 40,
> > > + CMDQ_EVENT_DISP_RDMA0_EOF = 41,
> > > + CMDQ_EVENT_DISP_RDMA1_EOF = 42,
> > > + CMDQ_EVENT_DISP_RDMA2_EOF = 43,
> > > + CMDQ_EVENT_DISP_WDMA0_EOF = 44,
> > > + CMDQ_EVENT_DISP_WDMA1_EOF = 45,
> > > + /* Mutex end of frame(EOF) events */
> > > + CMDQ_EVENT_MUTEX0_STREAM_EOF = 53,
> > > + CMDQ_EVENT_MUTEX1_STREAM_EOF = 54,
> > > + CMDQ_EVENT_MUTEX2_STREAM_EOF = 55,
> > > + CMDQ_EVENT_MUTEX3_STREAM_EOF = 56,
> > > + CMDQ_EVENT_MUTEX4_STREAM_EOF = 57,
> > > + /* Display underrun events */
> > > + CMDQ_EVENT_DISP_RDMA0_UNDERRUN = 63,
> > > + CMDQ_EVENT_DISP_RDMA1_UNDERRUN = 64,
> > > + CMDQ_EVENT_DISP_RDMA2_UNDERRUN = 65,
> > > + /* Keep this at the end of HW events */
> > > + CMDQ_MAX_HW_EVENT_COUNT = 260,
> > > +};
> > 
> > The value of these symbol is just the GCE-HW-defined value. I think it's
> > not appropriate to expose HW-defined value to client. For another SoC
> > GCE HW, these definition may change.
> 
> Agree.
> 
> > One way to solve this problem is to translate symbol to value
> > internally. But these events looks like interrupt and the value may vary
> > by each SoC, to prevent driver modified frequently, it's better to place
> > the value definition in device tree. It may looks like:
> > 
> > mmsys: clock-controller@1400 {
> > compatible = "mediatek,mt8173-mmsys";
> > mediatek,gce = <>;
> > gce-events = <53 54>;
> 
> However, client still needs to know the HW-defined value by using
> this solution.
> 
> > gce-event-names = "MUTEX0_EOF","MUTEX1_EOF";
> > }
> > 
> > For cmdq driver, you just need modify interface from
> > 
> > int cmdq_rec_wfe(struct cmdq_rec *rec, enum cmdq_event event)
> > int cmdq_rec_clear_event(struct cmdq_rec *rec, enum cmdq_event event)
> > 
> > to
> > 
> > int cmdq_rec_wfe(struct cmdq_rec *rec, u32 event)
> > int cmdq_rec_clear_event(struct cmdq_rec *rec, u32 event)
> 
> I think an easy way for this issue is just removing HW-defined values
> from include/soc/mediatek/cmdq.h (but keeping enum), and then mapping
> abstract values into real values in driver.
> The benefit of this solution is that we can keep interface and leave SoC
> specific code into driver.
> What do you think?

Hi, HS:

OK, that's fine.

Regards,
CK

> 
> > Regards,
> > CK
> 
> Thanks,
> HS
> 
> 




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-23 Thread Horng-Shyang Liao
Hi CK,

On Thu, 2016-06-23 at 14:03 +0800, CK Hu wrote:
> Hi, HS:
> 
> On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> [...]
> 
> > +
> > +/* events for CMDQ and display */
> > +enum cmdq_event {
> > +   /* Display start of frame(SOF) events */
> > +   CMDQ_EVENT_DISP_OVL0_SOF = 11,
> > +   CMDQ_EVENT_DISP_OVL1_SOF = 12,
> > +   CMDQ_EVENT_DISP_RDMA0_SOF = 13,
> > +   CMDQ_EVENT_DISP_RDMA1_SOF = 14,
> > +   CMDQ_EVENT_DISP_RDMA2_SOF = 15,
> > +   CMDQ_EVENT_DISP_WDMA0_SOF = 16,
> > +   CMDQ_EVENT_DISP_WDMA1_SOF = 17,
> > +   /* Display end of frame(EOF) events */
> > +   CMDQ_EVENT_DISP_OVL0_EOF = 39,
> > +   CMDQ_EVENT_DISP_OVL1_EOF = 40,
> > +   CMDQ_EVENT_DISP_RDMA0_EOF = 41,
> > +   CMDQ_EVENT_DISP_RDMA1_EOF = 42,
> > +   CMDQ_EVENT_DISP_RDMA2_EOF = 43,
> > +   CMDQ_EVENT_DISP_WDMA0_EOF = 44,
> > +   CMDQ_EVENT_DISP_WDMA1_EOF = 45,
> > +   /* Mutex end of frame(EOF) events */
> > +   CMDQ_EVENT_MUTEX0_STREAM_EOF = 53,
> > +   CMDQ_EVENT_MUTEX1_STREAM_EOF = 54,
> > +   CMDQ_EVENT_MUTEX2_STREAM_EOF = 55,
> > +   CMDQ_EVENT_MUTEX3_STREAM_EOF = 56,
> > +   CMDQ_EVENT_MUTEX4_STREAM_EOF = 57,
> > +   /* Display underrun events */
> > +   CMDQ_EVENT_DISP_RDMA0_UNDERRUN = 63,
> > +   CMDQ_EVENT_DISP_RDMA1_UNDERRUN = 64,
> > +   CMDQ_EVENT_DISP_RDMA2_UNDERRUN = 65,
> > +   /* Keep this at the end of HW events */
> > +   CMDQ_MAX_HW_EVENT_COUNT = 260,
> > +};
> 
> The value of these symbol is just the GCE-HW-defined value. I think it's
> not appropriate to expose HW-defined value to client. For another SoC
> GCE HW, these definition may change.

Agree.

> One way to solve this problem is to translate symbol to value
> internally. But these events looks like interrupt and the value may vary
> by each SoC, to prevent driver modified frequently, it's better to place
> the value definition in device tree. It may looks like:
> 
> mmsys: clock-controller@1400 {
>   compatible = "mediatek,mt8173-mmsys";
>   mediatek,gce = <>;
>   gce-events = <53 54>;

However, client still needs to know the HW-defined value by using
this solution.

>   gce-event-names = "MUTEX0_EOF","MUTEX1_EOF";
> }
> 
> For cmdq driver, you just need modify interface from
> 
> int cmdq_rec_wfe(struct cmdq_rec *rec, enum cmdq_event event)
> int cmdq_rec_clear_event(struct cmdq_rec *rec, enum cmdq_event event)
> 
> to
> 
> int cmdq_rec_wfe(struct cmdq_rec *rec, u32 event)
> int cmdq_rec_clear_event(struct cmdq_rec *rec, u32 event)

I think an easy way for this issue is just removing HW-defined values
from include/soc/mediatek/cmdq.h (but keeping enum), and then mapping
abstract values into real values in driver.
The benefit of this solution is that we can keep interface and leave SoC
specific code into driver.
What do you think?

> Regards,
> CK

Thanks,
HS




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-23 Thread Horng-Shyang Liao
Hi CK,

On Thu, 2016-06-23 at 14:03 +0800, CK Hu wrote:
> Hi, HS:
> 
> On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> [...]
> 
> > +
> > +/* events for CMDQ and display */
> > +enum cmdq_event {
> > +   /* Display start of frame(SOF) events */
> > +   CMDQ_EVENT_DISP_OVL0_SOF = 11,
> > +   CMDQ_EVENT_DISP_OVL1_SOF = 12,
> > +   CMDQ_EVENT_DISP_RDMA0_SOF = 13,
> > +   CMDQ_EVENT_DISP_RDMA1_SOF = 14,
> > +   CMDQ_EVENT_DISP_RDMA2_SOF = 15,
> > +   CMDQ_EVENT_DISP_WDMA0_SOF = 16,
> > +   CMDQ_EVENT_DISP_WDMA1_SOF = 17,
> > +   /* Display end of frame(EOF) events */
> > +   CMDQ_EVENT_DISP_OVL0_EOF = 39,
> > +   CMDQ_EVENT_DISP_OVL1_EOF = 40,
> > +   CMDQ_EVENT_DISP_RDMA0_EOF = 41,
> > +   CMDQ_EVENT_DISP_RDMA1_EOF = 42,
> > +   CMDQ_EVENT_DISP_RDMA2_EOF = 43,
> > +   CMDQ_EVENT_DISP_WDMA0_EOF = 44,
> > +   CMDQ_EVENT_DISP_WDMA1_EOF = 45,
> > +   /* Mutex end of frame(EOF) events */
> > +   CMDQ_EVENT_MUTEX0_STREAM_EOF = 53,
> > +   CMDQ_EVENT_MUTEX1_STREAM_EOF = 54,
> > +   CMDQ_EVENT_MUTEX2_STREAM_EOF = 55,
> > +   CMDQ_EVENT_MUTEX3_STREAM_EOF = 56,
> > +   CMDQ_EVENT_MUTEX4_STREAM_EOF = 57,
> > +   /* Display underrun events */
> > +   CMDQ_EVENT_DISP_RDMA0_UNDERRUN = 63,
> > +   CMDQ_EVENT_DISP_RDMA1_UNDERRUN = 64,
> > +   CMDQ_EVENT_DISP_RDMA2_UNDERRUN = 65,
> > +   /* Keep this at the end of HW events */
> > +   CMDQ_MAX_HW_EVENT_COUNT = 260,
> > +};
> 
> The value of these symbol is just the GCE-HW-defined value. I think it's
> not appropriate to expose HW-defined value to client. For another SoC
> GCE HW, these definition may change.

Agree.

> One way to solve this problem is to translate symbol to value
> internally. But these events looks like interrupt and the value may vary
> by each SoC, to prevent driver modified frequently, it's better to place
> the value definition in device tree. It may looks like:
> 
> mmsys: clock-controller@1400 {
>   compatible = "mediatek,mt8173-mmsys";
>   mediatek,gce = <>;
>   gce-events = <53 54>;

However, client still needs to know the HW-defined value by using
this solution.

>   gce-event-names = "MUTEX0_EOF","MUTEX1_EOF";
> }
> 
> For cmdq driver, you just need modify interface from
> 
> int cmdq_rec_wfe(struct cmdq_rec *rec, enum cmdq_event event)
> int cmdq_rec_clear_event(struct cmdq_rec *rec, enum cmdq_event event)
> 
> to
> 
> int cmdq_rec_wfe(struct cmdq_rec *rec, u32 event)
> int cmdq_rec_clear_event(struct cmdq_rec *rec, u32 event)

I think an easy way for this issue is just removing HW-defined values
from include/soc/mediatek/cmdq.h (but keeping enum), and then mapping
abstract values into real values in driver.
The benefit of this solution is that we can keep interface and leave SoC
specific code into driver.
What do you think?

> Regards,
> CK

Thanks,
HS




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-23 Thread CK Hu
Hi, HS:

On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help read/write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao 
> Signed-off-by: CK Hu 
> ---
>  drivers/soc/mediatek/Kconfig|  10 +
>  drivers/soc/mediatek/Makefile   |   1 +
>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> 
>  include/soc/mediatek/cmdq.h | 197 +
>  4 files changed, 1151 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
>  create mode 100644 include/soc/mediatek/cmdq.h

[...]

> +
> +/* events for CMDQ and display */
> +enum cmdq_event {
> + /* Display start of frame(SOF) events */
> + CMDQ_EVENT_DISP_OVL0_SOF = 11,
> + CMDQ_EVENT_DISP_OVL1_SOF = 12,
> + CMDQ_EVENT_DISP_RDMA0_SOF = 13,
> + CMDQ_EVENT_DISP_RDMA1_SOF = 14,
> + CMDQ_EVENT_DISP_RDMA2_SOF = 15,
> + CMDQ_EVENT_DISP_WDMA0_SOF = 16,
> + CMDQ_EVENT_DISP_WDMA1_SOF = 17,
> + /* Display end of frame(EOF) events */
> + CMDQ_EVENT_DISP_OVL0_EOF = 39,
> + CMDQ_EVENT_DISP_OVL1_EOF = 40,
> + CMDQ_EVENT_DISP_RDMA0_EOF = 41,
> + CMDQ_EVENT_DISP_RDMA1_EOF = 42,
> + CMDQ_EVENT_DISP_RDMA2_EOF = 43,
> + CMDQ_EVENT_DISP_WDMA0_EOF = 44,
> + CMDQ_EVENT_DISP_WDMA1_EOF = 45,
> + /* Mutex end of frame(EOF) events */
> + CMDQ_EVENT_MUTEX0_STREAM_EOF = 53,
> + CMDQ_EVENT_MUTEX1_STREAM_EOF = 54,
> + CMDQ_EVENT_MUTEX2_STREAM_EOF = 55,
> + CMDQ_EVENT_MUTEX3_STREAM_EOF = 56,
> + CMDQ_EVENT_MUTEX4_STREAM_EOF = 57,
> + /* Display underrun events */
> + CMDQ_EVENT_DISP_RDMA0_UNDERRUN = 63,
> + CMDQ_EVENT_DISP_RDMA1_UNDERRUN = 64,
> + CMDQ_EVENT_DISP_RDMA2_UNDERRUN = 65,
> + /* Keep this at the end of HW events */
> + CMDQ_MAX_HW_EVENT_COUNT = 260,
> +};

The value of these symbol is just the GCE-HW-defined value. I think it's
not appropriate to expose HW-defined value to client. For another SoC
GCE HW, these definition may change.

One way to solve this problem is to translate symbol to value
internally. But these events looks like interrupt and the value may vary
by each SoC, to prevent driver modified frequently, it's better to place
the value definition in device tree. It may looks like:

mmsys: clock-controller@1400 {
compatible = "mediatek,mt8173-mmsys";
mediatek,gce = <>;
gce-events = <53 54>;
gce-event-names = "MUTEX0_EOF","MUTEX1_EOF";
}

For cmdq driver, you just need modify interface from

int cmdq_rec_wfe(struct cmdq_rec *rec, enum cmdq_event event)
int cmdq_rec_clear_event(struct cmdq_rec *rec, enum cmdq_event event)

to

int cmdq_rec_wfe(struct cmdq_rec *rec, u32 event)
int cmdq_rec_clear_event(struct cmdq_rec *rec, u32 event)

Regards,
CK




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-23 Thread CK Hu
Hi, HS:

On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help read/write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao 
> Signed-off-by: CK Hu 
> ---
>  drivers/soc/mediatek/Kconfig|  10 +
>  drivers/soc/mediatek/Makefile   |   1 +
>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> 
>  include/soc/mediatek/cmdq.h | 197 +
>  4 files changed, 1151 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
>  create mode 100644 include/soc/mediatek/cmdq.h

[...]

> +
> +/* events for CMDQ and display */
> +enum cmdq_event {
> + /* Display start of frame(SOF) events */
> + CMDQ_EVENT_DISP_OVL0_SOF = 11,
> + CMDQ_EVENT_DISP_OVL1_SOF = 12,
> + CMDQ_EVENT_DISP_RDMA0_SOF = 13,
> + CMDQ_EVENT_DISP_RDMA1_SOF = 14,
> + CMDQ_EVENT_DISP_RDMA2_SOF = 15,
> + CMDQ_EVENT_DISP_WDMA0_SOF = 16,
> + CMDQ_EVENT_DISP_WDMA1_SOF = 17,
> + /* Display end of frame(EOF) events */
> + CMDQ_EVENT_DISP_OVL0_EOF = 39,
> + CMDQ_EVENT_DISP_OVL1_EOF = 40,
> + CMDQ_EVENT_DISP_RDMA0_EOF = 41,
> + CMDQ_EVENT_DISP_RDMA1_EOF = 42,
> + CMDQ_EVENT_DISP_RDMA2_EOF = 43,
> + CMDQ_EVENT_DISP_WDMA0_EOF = 44,
> + CMDQ_EVENT_DISP_WDMA1_EOF = 45,
> + /* Mutex end of frame(EOF) events */
> + CMDQ_EVENT_MUTEX0_STREAM_EOF = 53,
> + CMDQ_EVENT_MUTEX1_STREAM_EOF = 54,
> + CMDQ_EVENT_MUTEX2_STREAM_EOF = 55,
> + CMDQ_EVENT_MUTEX3_STREAM_EOF = 56,
> + CMDQ_EVENT_MUTEX4_STREAM_EOF = 57,
> + /* Display underrun events */
> + CMDQ_EVENT_DISP_RDMA0_UNDERRUN = 63,
> + CMDQ_EVENT_DISP_RDMA1_UNDERRUN = 64,
> + CMDQ_EVENT_DISP_RDMA2_UNDERRUN = 65,
> + /* Keep this at the end of HW events */
> + CMDQ_MAX_HW_EVENT_COUNT = 260,
> +};

The value of these symbol is just the GCE-HW-defined value. I think it's
not appropriate to expose HW-defined value to client. For another SoC
GCE HW, these definition may change.

One way to solve this problem is to translate symbol to value
internally. But these events looks like interrupt and the value may vary
by each SoC, to prevent driver modified frequently, it's better to place
the value definition in device tree. It may looks like:

mmsys: clock-controller@1400 {
compatible = "mediatek,mt8173-mmsys";
mediatek,gce = <>;
gce-events = <53 54>;
gce-event-names = "MUTEX0_EOF","MUTEX1_EOF";
}

For cmdq driver, you just need modify interface from

int cmdq_rec_wfe(struct cmdq_rec *rec, enum cmdq_event event)
int cmdq_rec_clear_event(struct cmdq_rec *rec, enum cmdq_event event)

to

int cmdq_rec_wfe(struct cmdq_rec *rec, u32 event)
int cmdq_rec_clear_event(struct cmdq_rec *rec, u32 event)

Regards,
CK




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-22 Thread Matthias Brugger



On 06/22/2016 07:43 AM, Horng-Shyang Liao wrote:

On Tue, 2016-06-21 at 15:41 +0200, Matthias Brugger wrote:


On 21/06/16 07:52, Horng-Shyang Liao wrote:

On Fri, 2016-06-17 at 17:57 +0200, Matthias Brugger wrote:


On 17/06/16 10:28, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:


On 14/06/16 09:44, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:


On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
From CPU's point of view, tasks are linked by the busy list.
From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


 From my understanding, your proposed 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-22 Thread Matthias Brugger



On 06/22/2016 07:43 AM, Horng-Shyang Liao wrote:

On Tue, 2016-06-21 at 15:41 +0200, Matthias Brugger wrote:


On 21/06/16 07:52, Horng-Shyang Liao wrote:

On Fri, 2016-06-17 at 17:57 +0200, Matthias Brugger wrote:


On 17/06/16 10:28, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:


On 14/06/16 09:44, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:


On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
From CPU's point of view, tasks are linked by the busy list.
From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


 From my understanding, your proposed 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-21 Thread Horng-Shyang Liao
On Tue, 2016-06-21 at 15:41 +0200, Matthias Brugger wrote:
> 
> On 21/06/16 07:52, Horng-Shyang Liao wrote:
> > On Fri, 2016-06-17 at 17:57 +0200, Matthias Brugger wrote:
> >>
> >> On 17/06/16 10:28, Horng-Shyang Liao wrote:
> >>> Hi Matthias,
> >>>
> >>> On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:
>  Hi Matthias,
> 
>  On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:
> >
> > On 14/06/16 09:44, Horng-Shyang Liao wrote:
> >> Hi Matthias,
> >>
> >> On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:
> >>>
> >>> On 08/06/16 14:25, Horng-Shyang Liao wrote:
>  Hi Matthias,
> 
>  On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> >
> > On 08/06/16 07:40, Horng-Shyang Liao wrote:
> >> Hi Matthias,
> >>
> >> On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> >>>
> >>> On 03/06/16 15:11, Matthias Brugger wrote:
> 
> 
> >>> [...]
> >>>
> > +
> > +smp_mb(); /* modify jump before enable 
> > thread */
> > +}
> > +
> > +cmdq_thread_writel(thread, task->pa_base +
> > task->command_size,
> > +   CMDQ_THR_END_ADDR);
> > +cmdq_thread_resume(thread);
> > +}
> > +list_move_tail(>list_entry, 
> > >task_busy_list);
> > +spin_unlock_irqrestore(>exec_lock, flags);
> > +}
> > +
> > +static void cmdq_handle_error_done(struct cmdq *cmdq,
> > +   struct cmdq_thread *thread, u32 
> > irq_flag)
> > +{
> > +struct cmdq_task *task, *tmp, *curr_task = NULL;
> > +u32 curr_pa;
> > +struct cmdq_cb_data cmdq_cb_data;
> > +bool err;
> > +
> > +if (irq_flag & CMDQ_THR_IRQ_ERROR)
> > +err = true;
> > +else if (irq_flag & CMDQ_THR_IRQ_DONE)
> > +err = false;
> > +else
> > +return;
> > +
> > +curr_pa = cmdq_thread_readl(thread, 
> > CMDQ_THR_CURR_ADDR);
> > +
> > +list_for_each_entry_safe(task, tmp, 
> > >task_busy_list,
> > + list_entry) {
> > +if (curr_pa >= task->pa_base &&
> > +curr_pa < (task->pa_base + 
> > task->command_size))
> 
>  What are you checking here? It seems as if you make some 
>  implcit
>  assumptions about pa_base and the order of execution of
>  commands in the
>  thread. Is it save to do so? Does dma_alloc_coherent 
>  give any
>  guarantees
>  about dma_handle?
> >>>
> >>> 1. Check what is the current running task in this GCE 
> >>> thread.
> >>> 2. Yes.
> >>> 3. Yes, CMDQ doesn't use iommu, so physical address is 
> >>> continuous.
> >>>
> >>
> >> Yes, physical addresses might be continous, but AFAIK 
> >> there is no
> >> guarantee that the dma_handle address is steadily growing, 
> >> when
> >> calling
> >> dma_alloc_coherent. And if I understand the code 
> >> correctly, you
> >> use this
> >> assumption to decide if the task picked from 
> >> task_busy_list is
> >> currently
> >> executing. So I think this mecanism is not working.
> >
> > I don't use dma_handle address, and just use physical 
> > addresses.
> > From CPU's point of view, tasks are linked by the 
> > busy list.
> > From GCE's point of view, tasks are linked by the 
> > JUMP command.
> >
> >> In which cases does the HW thread raise an interrupt.
> >> In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> >
> > GCE will raise interrupt if any task is done or error.
> > 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-21 Thread Horng-Shyang Liao
On Tue, 2016-06-21 at 15:41 +0200, Matthias Brugger wrote:
> 
> On 21/06/16 07:52, Horng-Shyang Liao wrote:
> > On Fri, 2016-06-17 at 17:57 +0200, Matthias Brugger wrote:
> >>
> >> On 17/06/16 10:28, Horng-Shyang Liao wrote:
> >>> Hi Matthias,
> >>>
> >>> On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:
>  Hi Matthias,
> 
>  On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:
> >
> > On 14/06/16 09:44, Horng-Shyang Liao wrote:
> >> Hi Matthias,
> >>
> >> On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:
> >>>
> >>> On 08/06/16 14:25, Horng-Shyang Liao wrote:
>  Hi Matthias,
> 
>  On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> >
> > On 08/06/16 07:40, Horng-Shyang Liao wrote:
> >> Hi Matthias,
> >>
> >> On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> >>>
> >>> On 03/06/16 15:11, Matthias Brugger wrote:
> 
> 
> >>> [...]
> >>>
> > +
> > +smp_mb(); /* modify jump before enable 
> > thread */
> > +}
> > +
> > +cmdq_thread_writel(thread, task->pa_base +
> > task->command_size,
> > +   CMDQ_THR_END_ADDR);
> > +cmdq_thread_resume(thread);
> > +}
> > +list_move_tail(>list_entry, 
> > >task_busy_list);
> > +spin_unlock_irqrestore(>exec_lock, flags);
> > +}
> > +
> > +static void cmdq_handle_error_done(struct cmdq *cmdq,
> > +   struct cmdq_thread *thread, u32 
> > irq_flag)
> > +{
> > +struct cmdq_task *task, *tmp, *curr_task = NULL;
> > +u32 curr_pa;
> > +struct cmdq_cb_data cmdq_cb_data;
> > +bool err;
> > +
> > +if (irq_flag & CMDQ_THR_IRQ_ERROR)
> > +err = true;
> > +else if (irq_flag & CMDQ_THR_IRQ_DONE)
> > +err = false;
> > +else
> > +return;
> > +
> > +curr_pa = cmdq_thread_readl(thread, 
> > CMDQ_THR_CURR_ADDR);
> > +
> > +list_for_each_entry_safe(task, tmp, 
> > >task_busy_list,
> > + list_entry) {
> > +if (curr_pa >= task->pa_base &&
> > +curr_pa < (task->pa_base + 
> > task->command_size))
> 
>  What are you checking here? It seems as if you make some 
>  implcit
>  assumptions about pa_base and the order of execution of
>  commands in the
>  thread. Is it save to do so? Does dma_alloc_coherent 
>  give any
>  guarantees
>  about dma_handle?
> >>>
> >>> 1. Check what is the current running task in this GCE 
> >>> thread.
> >>> 2. Yes.
> >>> 3. Yes, CMDQ doesn't use iommu, so physical address is 
> >>> continuous.
> >>>
> >>
> >> Yes, physical addresses might be continous, but AFAIK 
> >> there is no
> >> guarantee that the dma_handle address is steadily growing, 
> >> when
> >> calling
> >> dma_alloc_coherent. And if I understand the code 
> >> correctly, you
> >> use this
> >> assumption to decide if the task picked from 
> >> task_busy_list is
> >> currently
> >> executing. So I think this mecanism is not working.
> >
> > I don't use dma_handle address, and just use physical 
> > addresses.
> > From CPU's point of view, tasks are linked by the 
> > busy list.
> > From GCE's point of view, tasks are linked by the 
> > JUMP command.
> >
> >> In which cases does the HW thread raise an interrupt.
> >> In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> >
> > GCE will raise interrupt if any task is done or error.
> > 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-21 Thread Matthias Brugger



On 21/06/16 07:52, Horng-Shyang Liao wrote:

On Fri, 2016-06-17 at 17:57 +0200, Matthias Brugger wrote:


On 17/06/16 10:28, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:


On 14/06/16 09:44, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:


On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
From CPU's point of view, tasks are linked by the busy list.
From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


 From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-21 Thread Matthias Brugger



On 21/06/16 07:52, Horng-Shyang Liao wrote:

On Fri, 2016-06-17 at 17:57 +0200, Matthias Brugger wrote:


On 17/06/16 10:28, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:


On 14/06/16 09:44, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:


On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
From CPU's point of view, tasks are linked by the busy list.
From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


 From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-21 Thread Horng-Shyang Liao
On Tue, 2016-06-21 at 10:03 +0800, CK Hu wrote:
> On Mon, 2016-06-20 at 19:22 +0800, Horng-Shyang Liao wrote:
> > On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> > > Hi, HS:
> > > 
> > > One comment inline.
> > > 
> > > On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> > > > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > > > CMDQ is used to help read/write registers with critical time limitation,
> > > > such as updating display configuration during the vblank. It controls
> > > > Global Command Engine (GCE) hardware to achieve this requirement.
> > > > Currently, CMDQ only supports display related hardwares, but we expect
> > > > it can be extended to other hardwares for future requirements.
> > > > 
> > > > Signed-off-by: HS Liao 
> > > > Signed-off-by: CK Hu 
> > > > ---
> > > >  drivers/soc/mediatek/Kconfig|  10 +
> > > >  drivers/soc/mediatek/Makefile   |   1 +
> > > >  drivers/soc/mediatek/mtk-cmdq.c | 943 
> > > > 
> > > >  include/soc/mediatek/cmdq.h | 197 +
> > > >  4 files changed, 1151 insertions(+)
> > > >  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> > > >  create mode 100644 include/soc/mediatek/cmdq.h
> > > > 
> > > > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > > > index 0a4ea80..c4ad75c 100644
> > > > --- a/drivers/soc/mediatek/Kconfig
> > > > +++ b/drivers/soc/mediatek/Kconfig
> > > > @@ -1,6 +1,16 @@
> > > >  #
> > > >  # MediaTek SoC drivers
> > > >  #
> > > > +config MTK_CMDQ
> > > > +   bool "MediaTek CMDQ Support"
> > > > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > +   select MTK_INFRACFG
> > > > +   help
> > > > + Say yes here to add support for the MediaTek Command Queue 
> > > > (CMDQ)
> > > > + driver. The CMDQ is used to help read/write registers with 
> > > > critical
> > > > + time limitation, such as updating display configuration 
> > > > during the
> > > > + vblank.
> > > > +
> > > >  config MTK_INFRACFG
> > > > bool "MediaTek INFRACFG Support"
> > > > depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > diff --git a/drivers/soc/mediatek/Makefile 
> > > > b/drivers/soc/mediatek/Makefile
> > > > index 12998b0..f7397ef 100644
> > > > --- a/drivers/soc/mediatek/Makefile
> > > > +++ b/drivers/soc/mediatek/Makefile
> > > 
> > > [Snip...]
> > > 
> > > > +
> > > > +static int cmdq_eng_get_thread(u64 flag)
> > > > +{
> > > > +   if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > > > +   return CMDQ_THR_DISP_MAIN_IDX;
> > > > +   else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > > > +   return CMDQ_THR_DISP_SUB_IDX;
> > > > +   else
> > > > +   return CMDQ_THR_DISP_MISC_IDX;
> > > > +}
> > > 
> > > I think cmdq should not have knowledge of client. These statement show
> > > that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> > > the 'session' to replace engine flag. For example, main display create
> > > one cmdq_session and external display create another cmdq_session. For
> > > client driver, every tasks created by main display is bound to main
> > > display session. For cmdq driver, it should dynamically bind a session
> > > to a HW thread, and then dispatch tasks of this session to this HW
> > > thread. After HW thread run out of tasks of this session, detach this
> > > session with this thread.
> > > For the problem of remove wfe cmd, I think a session can have a property
> > > of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> > > For other client, it's false.
> > 
> > Hi CK,
> > 
> > I think your suggestion is similar to CMDQ 'scenarios',
> > which was removed from CMDQ v2.
> > 
> > Daniel suggests to use engine flags instead of scenarios.
> > Quote from https://patchwork.kernel.org/patch/8068311/ .
> > 'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
> >  cmdq driver should just provide these flag bits, and the display
> >  subsystem can use them to build the "flag" parameter itself.
> > 
> >  After all, the exact configuration of mmsys components is somewhat
> >  flexible.'
> > 
> > Therefore, it would be better to discuss with Daniel before we change
> > it.
> > 
> > 
> > Hi Daniel,
> > 
> > Do you think we should use scenarios or sessions instead of flags?
> > 
> > Thanks,
> > HS
> > 
> 
> Hi, HS:
> 
> 'session' is not similar to 'scenarios'.
> 
> In 'scenarios' mechanism, client bind a task with scenarios and send to
> cmdq. Cmdq transfer scenarios to engine flag, and use engine flag to
> dispatch task to HW thread.
> 
> 
> In 'engine flag' mechanism, proposed by Daniel, client bind a task
> directly with engine flag. Cmdq directly use engine flag to dispatch
> task to HW thread without any translation.
> 
> But neither 'scenarios' mechanism nor 'engine flag' mechanism get rid of
> engine flag, which make cmdq have knowledge of 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-21 Thread Horng-Shyang Liao
On Tue, 2016-06-21 at 10:03 +0800, CK Hu wrote:
> On Mon, 2016-06-20 at 19:22 +0800, Horng-Shyang Liao wrote:
> > On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> > > Hi, HS:
> > > 
> > > One comment inline.
> > > 
> > > On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> > > > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > > > CMDQ is used to help read/write registers with critical time limitation,
> > > > such as updating display configuration during the vblank. It controls
> > > > Global Command Engine (GCE) hardware to achieve this requirement.
> > > > Currently, CMDQ only supports display related hardwares, but we expect
> > > > it can be extended to other hardwares for future requirements.
> > > > 
> > > > Signed-off-by: HS Liao 
> > > > Signed-off-by: CK Hu 
> > > > ---
> > > >  drivers/soc/mediatek/Kconfig|  10 +
> > > >  drivers/soc/mediatek/Makefile   |   1 +
> > > >  drivers/soc/mediatek/mtk-cmdq.c | 943 
> > > > 
> > > >  include/soc/mediatek/cmdq.h | 197 +
> > > >  4 files changed, 1151 insertions(+)
> > > >  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> > > >  create mode 100644 include/soc/mediatek/cmdq.h
> > > > 
> > > > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > > > index 0a4ea80..c4ad75c 100644
> > > > --- a/drivers/soc/mediatek/Kconfig
> > > > +++ b/drivers/soc/mediatek/Kconfig
> > > > @@ -1,6 +1,16 @@
> > > >  #
> > > >  # MediaTek SoC drivers
> > > >  #
> > > > +config MTK_CMDQ
> > > > +   bool "MediaTek CMDQ Support"
> > > > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > +   select MTK_INFRACFG
> > > > +   help
> > > > + Say yes here to add support for the MediaTek Command Queue 
> > > > (CMDQ)
> > > > + driver. The CMDQ is used to help read/write registers with 
> > > > critical
> > > > + time limitation, such as updating display configuration 
> > > > during the
> > > > + vblank.
> > > > +
> > > >  config MTK_INFRACFG
> > > > bool "MediaTek INFRACFG Support"
> > > > depends on ARCH_MEDIATEK || COMPILE_TEST
> > > > diff --git a/drivers/soc/mediatek/Makefile 
> > > > b/drivers/soc/mediatek/Makefile
> > > > index 12998b0..f7397ef 100644
> > > > --- a/drivers/soc/mediatek/Makefile
> > > > +++ b/drivers/soc/mediatek/Makefile
> > > 
> > > [Snip...]
> > > 
> > > > +
> > > > +static int cmdq_eng_get_thread(u64 flag)
> > > > +{
> > > > +   if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > > > +   return CMDQ_THR_DISP_MAIN_IDX;
> > > > +   else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > > > +   return CMDQ_THR_DISP_SUB_IDX;
> > > > +   else
> > > > +   return CMDQ_THR_DISP_MISC_IDX;
> > > > +}
> > > 
> > > I think cmdq should not have knowledge of client. These statement show
> > > that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> > > the 'session' to replace engine flag. For example, main display create
> > > one cmdq_session and external display create another cmdq_session. For
> > > client driver, every tasks created by main display is bound to main
> > > display session. For cmdq driver, it should dynamically bind a session
> > > to a HW thread, and then dispatch tasks of this session to this HW
> > > thread. After HW thread run out of tasks of this session, detach this
> > > session with this thread.
> > > For the problem of remove wfe cmd, I think a session can have a property
> > > of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> > > For other client, it's false.
> > 
> > Hi CK,
> > 
> > I think your suggestion is similar to CMDQ 'scenarios',
> > which was removed from CMDQ v2.
> > 
> > Daniel suggests to use engine flags instead of scenarios.
> > Quote from https://patchwork.kernel.org/patch/8068311/ .
> > 'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
> >  cmdq driver should just provide these flag bits, and the display
> >  subsystem can use them to build the "flag" parameter itself.
> > 
> >  After all, the exact configuration of mmsys components is somewhat
> >  flexible.'
> > 
> > Therefore, it would be better to discuss with Daniel before we change
> > it.
> > 
> > 
> > Hi Daniel,
> > 
> > Do you think we should use scenarios or sessions instead of flags?
> > 
> > Thanks,
> > HS
> > 
> 
> Hi, HS:
> 
> 'session' is not similar to 'scenarios'.
> 
> In 'scenarios' mechanism, client bind a task with scenarios and send to
> cmdq. Cmdq transfer scenarios to engine flag, and use engine flag to
> dispatch task to HW thread.
> 
> 
> In 'engine flag' mechanism, proposed by Daniel, client bind a task
> directly with engine flag. Cmdq directly use engine flag to dispatch
> task to HW thread without any translation.
> 
> But neither 'scenarios' mechanism nor 'engine flag' mechanism get rid of
> engine flag, which make cmdq have knowledge of client.
> 
> In 'session' mechanism, there is 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-20 Thread Horng-Shyang Liao
On Fri, 2016-06-17 at 17:57 +0200, Matthias Brugger wrote:
> 
> On 17/06/16 10:28, Horng-Shyang Liao wrote:
> > Hi Matthias,
> >
> > On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:
> >> Hi Matthias,
> >>
> >> On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:
> >>>
> >>> On 14/06/16 09:44, Horng-Shyang Liao wrote:
>  Hi Matthias,
> 
>  On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:
> >
> > On 08/06/16 14:25, Horng-Shyang Liao wrote:
> >> Hi Matthias,
> >>
> >> On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> >>>
> >>> On 08/06/16 07:40, Horng-Shyang Liao wrote:
>  Hi Matthias,
> 
>  On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> >
> > On 03/06/16 15:11, Matthias Brugger wrote:
> >>
> >>
> > [...]
> >
> >>> +
> >>> +smp_mb(); /* modify jump before enable 
> >>> thread */
> >>> +}
> >>> +
> >>> +cmdq_thread_writel(thread, task->pa_base +
> >>> task->command_size,
> >>> +   CMDQ_THR_END_ADDR);
> >>> +cmdq_thread_resume(thread);
> >>> +}
> >>> +list_move_tail(>list_entry, 
> >>> >task_busy_list);
> >>> +spin_unlock_irqrestore(>exec_lock, flags);
> >>> +}
> >>> +
> >>> +static void cmdq_handle_error_done(struct cmdq *cmdq,
> >>> +   struct cmdq_thread *thread, u32 
> >>> irq_flag)
> >>> +{
> >>> +struct cmdq_task *task, *tmp, *curr_task = NULL;
> >>> +u32 curr_pa;
> >>> +struct cmdq_cb_data cmdq_cb_data;
> >>> +bool err;
> >>> +
> >>> +if (irq_flag & CMDQ_THR_IRQ_ERROR)
> >>> +err = true;
> >>> +else if (irq_flag & CMDQ_THR_IRQ_DONE)
> >>> +err = false;
> >>> +else
> >>> +return;
> >>> +
> >>> +curr_pa = cmdq_thread_readl(thread, 
> >>> CMDQ_THR_CURR_ADDR);
> >>> +
> >>> +list_for_each_entry_safe(task, tmp, 
> >>> >task_busy_list,
> >>> + list_entry) {
> >>> +if (curr_pa >= task->pa_base &&
> >>> +curr_pa < (task->pa_base + 
> >>> task->command_size))
> >>
> >> What are you checking here? It seems as if you make some 
> >> implcit
> >> assumptions about pa_base and the order of execution of
> >> commands in the
> >> thread. Is it save to do so? Does dma_alloc_coherent give 
> >> any
> >> guarantees
> >> about dma_handle?
> >
> > 1. Check what is the current running task in this GCE 
> > thread.
> > 2. Yes.
> > 3. Yes, CMDQ doesn't use iommu, so physical address is 
> > continuous.
> >
> 
>  Yes, physical addresses might be continous, but AFAIK there 
>  is no
>  guarantee that the dma_handle address is steadily growing, 
>  when
>  calling
>  dma_alloc_coherent. And if I understand the code correctly, 
>  you
>  use this
>  assumption to decide if the task picked from task_busy_list 
>  is
>  currently
>  executing. So I think this mecanism is not working.
> >>>
> >>> I don't use dma_handle address, and just use physical 
> >>> addresses.
> >>>From CPU's point of view, tasks are linked by the busy 
> >>> list.
> >>>From GCE's point of view, tasks are linked by the JUMP 
> >>> command.
> >>>
>  In which cases does the HW thread raise an interrupt.
>  In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> >>>
> >>> GCE will raise interrupt if any task is done or error.
> >>> However, GCE is fast, so CPU may get multiple done tasks
> >>> when it is running ISR.
> >>>
> >>> In case of error, that GCE thread will pause and raise 
> >>> interrupt.
> >>> So, CPU may get multiple done tasks and one error task.
> >>>
> >>
> 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-20 Thread Horng-Shyang Liao
On Fri, 2016-06-17 at 17:57 +0200, Matthias Brugger wrote:
> 
> On 17/06/16 10:28, Horng-Shyang Liao wrote:
> > Hi Matthias,
> >
> > On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:
> >> Hi Matthias,
> >>
> >> On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:
> >>>
> >>> On 14/06/16 09:44, Horng-Shyang Liao wrote:
>  Hi Matthias,
> 
>  On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:
> >
> > On 08/06/16 14:25, Horng-Shyang Liao wrote:
> >> Hi Matthias,
> >>
> >> On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> >>>
> >>> On 08/06/16 07:40, Horng-Shyang Liao wrote:
>  Hi Matthias,
> 
>  On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> >
> > On 03/06/16 15:11, Matthias Brugger wrote:
> >>
> >>
> > [...]
> >
> >>> +
> >>> +smp_mb(); /* modify jump before enable 
> >>> thread */
> >>> +}
> >>> +
> >>> +cmdq_thread_writel(thread, task->pa_base +
> >>> task->command_size,
> >>> +   CMDQ_THR_END_ADDR);
> >>> +cmdq_thread_resume(thread);
> >>> +}
> >>> +list_move_tail(>list_entry, 
> >>> >task_busy_list);
> >>> +spin_unlock_irqrestore(>exec_lock, flags);
> >>> +}
> >>> +
> >>> +static void cmdq_handle_error_done(struct cmdq *cmdq,
> >>> +   struct cmdq_thread *thread, u32 
> >>> irq_flag)
> >>> +{
> >>> +struct cmdq_task *task, *tmp, *curr_task = NULL;
> >>> +u32 curr_pa;
> >>> +struct cmdq_cb_data cmdq_cb_data;
> >>> +bool err;
> >>> +
> >>> +if (irq_flag & CMDQ_THR_IRQ_ERROR)
> >>> +err = true;
> >>> +else if (irq_flag & CMDQ_THR_IRQ_DONE)
> >>> +err = false;
> >>> +else
> >>> +return;
> >>> +
> >>> +curr_pa = cmdq_thread_readl(thread, 
> >>> CMDQ_THR_CURR_ADDR);
> >>> +
> >>> +list_for_each_entry_safe(task, tmp, 
> >>> >task_busy_list,
> >>> + list_entry) {
> >>> +if (curr_pa >= task->pa_base &&
> >>> +curr_pa < (task->pa_base + 
> >>> task->command_size))
> >>
> >> What are you checking here? It seems as if you make some 
> >> implcit
> >> assumptions about pa_base and the order of execution of
> >> commands in the
> >> thread. Is it save to do so? Does dma_alloc_coherent give 
> >> any
> >> guarantees
> >> about dma_handle?
> >
> > 1. Check what is the current running task in this GCE 
> > thread.
> > 2. Yes.
> > 3. Yes, CMDQ doesn't use iommu, so physical address is 
> > continuous.
> >
> 
>  Yes, physical addresses might be continous, but AFAIK there 
>  is no
>  guarantee that the dma_handle address is steadily growing, 
>  when
>  calling
>  dma_alloc_coherent. And if I understand the code correctly, 
>  you
>  use this
>  assumption to decide if the task picked from task_busy_list 
>  is
>  currently
>  executing. So I think this mecanism is not working.
> >>>
> >>> I don't use dma_handle address, and just use physical 
> >>> addresses.
> >>>From CPU's point of view, tasks are linked by the busy 
> >>> list.
> >>>From GCE's point of view, tasks are linked by the JUMP 
> >>> command.
> >>>
>  In which cases does the HW thread raise an interrupt.
>  In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> >>>
> >>> GCE will raise interrupt if any task is done or error.
> >>> However, GCE is fast, so CPU may get multiple done tasks
> >>> when it is running ISR.
> >>>
> >>> In case of error, that GCE thread will pause and raise 
> >>> interrupt.
> >>> So, CPU may get multiple done tasks and one error task.
> >>>
> >>
> 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-20 Thread CK Hu
On Mon, 2016-06-20 at 19:22 +0800, Horng-Shyang Liao wrote:
> On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> > Hi, HS:
> > 
> > One comment inline.
> > 
> > On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> > > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > > CMDQ is used to help read/write registers with critical time limitation,
> > > such as updating display configuration during the vblank. It controls
> > > Global Command Engine (GCE) hardware to achieve this requirement.
> > > Currently, CMDQ only supports display related hardwares, but we expect
> > > it can be extended to other hardwares for future requirements.
> > > 
> > > Signed-off-by: HS Liao 
> > > Signed-off-by: CK Hu 
> > > ---
> > >  drivers/soc/mediatek/Kconfig|  10 +
> > >  drivers/soc/mediatek/Makefile   |   1 +
> > >  drivers/soc/mediatek/mtk-cmdq.c | 943 
> > > 
> > >  include/soc/mediatek/cmdq.h | 197 +
> > >  4 files changed, 1151 insertions(+)
> > >  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> > >  create mode 100644 include/soc/mediatek/cmdq.h
> > > 
> > > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > > index 0a4ea80..c4ad75c 100644
> > > --- a/drivers/soc/mediatek/Kconfig
> > > +++ b/drivers/soc/mediatek/Kconfig
> > > @@ -1,6 +1,16 @@
> > >  #
> > >  # MediaTek SoC drivers
> > >  #
> > > +config MTK_CMDQ
> > > + bool "MediaTek CMDQ Support"
> > > + depends on ARCH_MEDIATEK || COMPILE_TEST
> > > + select MTK_INFRACFG
> > > + help
> > > +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > > +   driver. The CMDQ is used to help read/write registers with critical
> > > +   time limitation, such as updating display configuration during the
> > > +   vblank.
> > > +
> > >  config MTK_INFRACFG
> > >   bool "MediaTek INFRACFG Support"
> > >   depends on ARCH_MEDIATEK || COMPILE_TEST
> > > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > > index 12998b0..f7397ef 100644
> > > --- a/drivers/soc/mediatek/Makefile
> > > +++ b/drivers/soc/mediatek/Makefile
> > 
> > [Snip...]
> > 
> > > +
> > > +static int cmdq_eng_get_thread(u64 flag)
> > > +{
> > > + if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > > + return CMDQ_THR_DISP_MAIN_IDX;
> > > + else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > > + return CMDQ_THR_DISP_SUB_IDX;
> > > + else
> > > + return CMDQ_THR_DISP_MISC_IDX;
> > > +}
> > 
> > I think cmdq should not have knowledge of client. These statement show
> > that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> > the 'session' to replace engine flag. For example, main display create
> > one cmdq_session and external display create another cmdq_session. For
> > client driver, every tasks created by main display is bound to main
> > display session. For cmdq driver, it should dynamically bind a session
> > to a HW thread, and then dispatch tasks of this session to this HW
> > thread. After HW thread run out of tasks of this session, detach this
> > session with this thread.
> > For the problem of remove wfe cmd, I think a session can have a property
> > of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> > For other client, it's false.
> 
> Hi CK,
> 
> I think your suggestion is similar to CMDQ 'scenarios',
> which was removed from CMDQ v2.
> 
> Daniel suggests to use engine flags instead of scenarios.
> Quote from https://patchwork.kernel.org/patch/8068311/ .
> 'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
>  cmdq driver should just provide these flag bits, and the display
>  subsystem can use them to build the "flag" parameter itself.
> 
>  After all, the exact configuration of mmsys components is somewhat
>  flexible.'
> 
> Therefore, it would be better to discuss with Daniel before we change
> it.
> 
> 
> Hi Daniel,
> 
> Do you think we should use scenarios or sessions instead of flags?
> 
> Thanks,
> HS
> 

Hi, HS:

'session' is not similar to 'scenarios'.

In 'scenarios' mechanism, client bind a task with scenarios and send to
cmdq. Cmdq transfer scenarios to engine flag, and use engine flag to
dispatch task to HW thread.


In 'engine flag' mechanism, proposed by Daniel, client bind a task
directly with engine flag. Cmdq directly use engine flag to dispatch
task to HW thread without any translation.

But neither 'scenarios' mechanism nor 'engine flag' mechanism get rid of
engine flag, which make cmdq have knowledge of client.

In 'session' mechanism, there is no engine flag any more. Client bind
time-sequential tasks to the same session and tasks in different session
can execute parallelly. One thing cmdq need to know is to dispatch tasks
with the same session to the same HW thread, so cmdq does not have any
knowledge of client.

Daniel focus on reduce translating scenarios to engine flag. I think
'session' mechanism does not 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-20 Thread CK Hu
On Mon, 2016-06-20 at 19:22 +0800, Horng-Shyang Liao wrote:
> On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> > Hi, HS:
> > 
> > One comment inline.
> > 
> > On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> > > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > > CMDQ is used to help read/write registers with critical time limitation,
> > > such as updating display configuration during the vblank. It controls
> > > Global Command Engine (GCE) hardware to achieve this requirement.
> > > Currently, CMDQ only supports display related hardwares, but we expect
> > > it can be extended to other hardwares for future requirements.
> > > 
> > > Signed-off-by: HS Liao 
> > > Signed-off-by: CK Hu 
> > > ---
> > >  drivers/soc/mediatek/Kconfig|  10 +
> > >  drivers/soc/mediatek/Makefile   |   1 +
> > >  drivers/soc/mediatek/mtk-cmdq.c | 943 
> > > 
> > >  include/soc/mediatek/cmdq.h | 197 +
> > >  4 files changed, 1151 insertions(+)
> > >  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> > >  create mode 100644 include/soc/mediatek/cmdq.h
> > > 
> > > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > > index 0a4ea80..c4ad75c 100644
> > > --- a/drivers/soc/mediatek/Kconfig
> > > +++ b/drivers/soc/mediatek/Kconfig
> > > @@ -1,6 +1,16 @@
> > >  #
> > >  # MediaTek SoC drivers
> > >  #
> > > +config MTK_CMDQ
> > > + bool "MediaTek CMDQ Support"
> > > + depends on ARCH_MEDIATEK || COMPILE_TEST
> > > + select MTK_INFRACFG
> > > + help
> > > +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > > +   driver. The CMDQ is used to help read/write registers with critical
> > > +   time limitation, such as updating display configuration during the
> > > +   vblank.
> > > +
> > >  config MTK_INFRACFG
> > >   bool "MediaTek INFRACFG Support"
> > >   depends on ARCH_MEDIATEK || COMPILE_TEST
> > > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > > index 12998b0..f7397ef 100644
> > > --- a/drivers/soc/mediatek/Makefile
> > > +++ b/drivers/soc/mediatek/Makefile
> > 
> > [Snip...]
> > 
> > > +
> > > +static int cmdq_eng_get_thread(u64 flag)
> > > +{
> > > + if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > > + return CMDQ_THR_DISP_MAIN_IDX;
> > > + else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > > + return CMDQ_THR_DISP_SUB_IDX;
> > > + else
> > > + return CMDQ_THR_DISP_MISC_IDX;
> > > +}
> > 
> > I think cmdq should not have knowledge of client. These statement show
> > that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> > the 'session' to replace engine flag. For example, main display create
> > one cmdq_session and external display create another cmdq_session. For
> > client driver, every tasks created by main display is bound to main
> > display session. For cmdq driver, it should dynamically bind a session
> > to a HW thread, and then dispatch tasks of this session to this HW
> > thread. After HW thread run out of tasks of this session, detach this
> > session with this thread.
> > For the problem of remove wfe cmd, I think a session can have a property
> > of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> > For other client, it's false.
> 
> Hi CK,
> 
> I think your suggestion is similar to CMDQ 'scenarios',
> which was removed from CMDQ v2.
> 
> Daniel suggests to use engine flags instead of scenarios.
> Quote from https://patchwork.kernel.org/patch/8068311/ .
> 'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
>  cmdq driver should just provide these flag bits, and the display
>  subsystem can use them to build the "flag" parameter itself.
> 
>  After all, the exact configuration of mmsys components is somewhat
>  flexible.'
> 
> Therefore, it would be better to discuss with Daniel before we change
> it.
> 
> 
> Hi Daniel,
> 
> Do you think we should use scenarios or sessions instead of flags?
> 
> Thanks,
> HS
> 

Hi, HS:

'session' is not similar to 'scenarios'.

In 'scenarios' mechanism, client bind a task with scenarios and send to
cmdq. Cmdq transfer scenarios to engine flag, and use engine flag to
dispatch task to HW thread.


In 'engine flag' mechanism, proposed by Daniel, client bind a task
directly with engine flag. Cmdq directly use engine flag to dispatch
task to HW thread without any translation.

But neither 'scenarios' mechanism nor 'engine flag' mechanism get rid of
engine flag, which make cmdq have knowledge of client.

In 'session' mechanism, there is no engine flag any more. Client bind
time-sequential tasks to the same session and tasks in different session
can execute parallelly. One thing cmdq need to know is to dispatch tasks
with the same session to the same HW thread, so cmdq does not have any
knowledge of client.

Daniel focus on reduce translating scenarios to engine flag. I think
'session' mechanism does not conflict with his opinion because we does
not 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-20 Thread Horng-Shyang Liao
On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> Hi, HS:
> 
> One comment inline.
> 
> On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help read/write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> > 
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> >  drivers/soc/mediatek/Kconfig|  10 +
> >  drivers/soc/mediatek/Makefile   |   1 +
> >  drivers/soc/mediatek/mtk-cmdq.c | 943 
> > 
> >  include/soc/mediatek/cmdq.h | 197 +
> >  4 files changed, 1151 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> >  create mode 100644 include/soc/mediatek/cmdq.h
> > 
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index 0a4ea80..c4ad75c 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -1,6 +1,16 @@
> >  #
> >  # MediaTek SoC drivers
> >  #
> > +config MTK_CMDQ
> > +   bool "MediaTek CMDQ Support"
> > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> > +   select MTK_INFRACFG
> > +   help
> > + Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > + driver. The CMDQ is used to help read/write registers with critical
> > + time limitation, such as updating display configuration during the
> > + vblank.
> > +
> >  config MTK_INFRACFG
> > bool "MediaTek INFRACFG Support"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..f7397ef 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> 
> [Snip...]
> 
> > +
> > +static int cmdq_eng_get_thread(u64 flag)
> > +{
> > +   if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > +   return CMDQ_THR_DISP_MAIN_IDX;
> > +   else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > +   return CMDQ_THR_DISP_SUB_IDX;
> > +   else
> > +   return CMDQ_THR_DISP_MISC_IDX;
> > +}
> 
> I think cmdq should not have knowledge of client. These statement show
> that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> the 'session' to replace engine flag. For example, main display create
> one cmdq_session and external display create another cmdq_session. For
> client driver, every tasks created by main display is bound to main
> display session. For cmdq driver, it should dynamically bind a session
> to a HW thread, and then dispatch tasks of this session to this HW
> thread. After HW thread run out of tasks of this session, detach this
> session with this thread.
> For the problem of remove wfe cmd, I think a session can have a property
> of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> For other client, it's false.

Hi CK,

I think your suggestion is similar to CMDQ 'scenarios',
which was removed from CMDQ v2.

Daniel suggests to use engine flags instead of scenarios.
Quote from https://patchwork.kernel.org/patch/8068311/ .
'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
 cmdq driver should just provide these flag bits, and the display
 subsystem can use them to build the "flag" parameter itself.

 After all, the exact configuration of mmsys components is somewhat
 flexible.'

Therefore, it would be better to discuss with Daniel before we change
it.


Hi Daniel,

Do you think we should use scenarios or sessions instead of flags?

Thanks,
HS

> Here is the sample code to create cmdq_rec with session.
> 
> merge_wfe_cmd = true;
> cmdq_session_create(merge_wfe_cmd, _display_session);
> cmdq_rec_create(dev, primary_display_session, );
> 
> 
> Therefore, the below definition can be removed.
> 
> > +
> > +enum cmdq_eng {
> > +   CMDQ_ENG_DISP_AAL,
> > +   CMDQ_ENG_DISP_COLOR0,
> > +   CMDQ_ENG_DISP_COLOR1,
> > +   CMDQ_ENG_DISP_DPI0,
> > +   CMDQ_ENG_DISP_DSI0,
> > +   CMDQ_ENG_DISP_DSI1,
> > +   CMDQ_ENG_DISP_GAMMA,
> > +   CMDQ_ENG_DISP_OD,
> > +   CMDQ_ENG_DISP_OVL0,
> > +   CMDQ_ENG_DISP_OVL1,
> > +   CMDQ_ENG_DISP_PWM0,
> > +   CMDQ_ENG_DISP_PWM1,
> > +   CMDQ_ENG_DISP_RDMA0,
> > +   CMDQ_ENG_DISP_RDMA1,
> > +   CMDQ_ENG_DISP_RDMA2,
> > +   CMDQ_ENG_DISP_UFOE,
> > +   CMDQ_ENG_DISP_WDMA0,
> > +   CMDQ_ENG_DISP_WDMA1,
> > +   CMDQ_ENG_MAX,
> > +};
> > +
> 
> 
> Regards,
> CK
> 




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-20 Thread Horng-Shyang Liao
On Mon, 2016-06-20 at 18:41 +0800, CK Hu wrote:
> Hi, HS:
> 
> One comment inline.
> 
> On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help read/write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> > 
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> >  drivers/soc/mediatek/Kconfig|  10 +
> >  drivers/soc/mediatek/Makefile   |   1 +
> >  drivers/soc/mediatek/mtk-cmdq.c | 943 
> > 
> >  include/soc/mediatek/cmdq.h | 197 +
> >  4 files changed, 1151 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> >  create mode 100644 include/soc/mediatek/cmdq.h
> > 
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index 0a4ea80..c4ad75c 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -1,6 +1,16 @@
> >  #
> >  # MediaTek SoC drivers
> >  #
> > +config MTK_CMDQ
> > +   bool "MediaTek CMDQ Support"
> > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> > +   select MTK_INFRACFG
> > +   help
> > + Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > + driver. The CMDQ is used to help read/write registers with critical
> > + time limitation, such as updating display configuration during the
> > + vblank.
> > +
> >  config MTK_INFRACFG
> > bool "MediaTek INFRACFG Support"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..f7397ef 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> 
> [Snip...]
> 
> > +
> > +static int cmdq_eng_get_thread(u64 flag)
> > +{
> > +   if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> > +   return CMDQ_THR_DISP_MAIN_IDX;
> > +   else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> > +   return CMDQ_THR_DISP_SUB_IDX;
> > +   else
> > +   return CMDQ_THR_DISP_MISC_IDX;
> > +}
> 
> I think cmdq should not have knowledge of client. These statement show
> that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
> the 'session' to replace engine flag. For example, main display create
> one cmdq_session and external display create another cmdq_session. For
> client driver, every tasks created by main display is bound to main
> display session. For cmdq driver, it should dynamically bind a session
> to a HW thread, and then dispatch tasks of this session to this HW
> thread. After HW thread run out of tasks of this session, detach this
> session with this thread.
> For the problem of remove wfe cmd, I think a session can have a property
> of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
> For other client, it's false.

Hi CK,

I think your suggestion is similar to CMDQ 'scenarios',
which was removed from CMDQ v2.

Daniel suggests to use engine flags instead of scenarios.
Quote from https://patchwork.kernel.org/patch/8068311/ .
'Instead of encoding policy (these arbitrary "scenarios"), perhaps the
 cmdq driver should just provide these flag bits, and the display
 subsystem can use them to build the "flag" parameter itself.

 After all, the exact configuration of mmsys components is somewhat
 flexible.'

Therefore, it would be better to discuss with Daniel before we change
it.


Hi Daniel,

Do you think we should use scenarios or sessions instead of flags?

Thanks,
HS

> Here is the sample code to create cmdq_rec with session.
> 
> merge_wfe_cmd = true;
> cmdq_session_create(merge_wfe_cmd, _display_session);
> cmdq_rec_create(dev, primary_display_session, );
> 
> 
> Therefore, the below definition can be removed.
> 
> > +
> > +enum cmdq_eng {
> > +   CMDQ_ENG_DISP_AAL,
> > +   CMDQ_ENG_DISP_COLOR0,
> > +   CMDQ_ENG_DISP_COLOR1,
> > +   CMDQ_ENG_DISP_DPI0,
> > +   CMDQ_ENG_DISP_DSI0,
> > +   CMDQ_ENG_DISP_DSI1,
> > +   CMDQ_ENG_DISP_GAMMA,
> > +   CMDQ_ENG_DISP_OD,
> > +   CMDQ_ENG_DISP_OVL0,
> > +   CMDQ_ENG_DISP_OVL1,
> > +   CMDQ_ENG_DISP_PWM0,
> > +   CMDQ_ENG_DISP_PWM1,
> > +   CMDQ_ENG_DISP_RDMA0,
> > +   CMDQ_ENG_DISP_RDMA1,
> > +   CMDQ_ENG_DISP_RDMA2,
> > +   CMDQ_ENG_DISP_UFOE,
> > +   CMDQ_ENG_DISP_WDMA0,
> > +   CMDQ_ENG_DISP_WDMA1,
> > +   CMDQ_ENG_MAX,
> > +};
> > +
> 
> 
> Regards,
> CK
> 




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-20 Thread CK Hu
Hi, HS:

One comment inline.

On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help read/write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao 
> Signed-off-by: CK Hu 
> ---
>  drivers/soc/mediatek/Kconfig|  10 +
>  drivers/soc/mediatek/Makefile   |   1 +
>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> 
>  include/soc/mediatek/cmdq.h | 197 +
>  4 files changed, 1151 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
>  create mode 100644 include/soc/mediatek/cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index 0a4ea80..c4ad75c 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -1,6 +1,16 @@
>  #
>  # MediaTek SoC drivers
>  #
> +config MTK_CMDQ
> + bool "MediaTek CMDQ Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select MTK_INFRACFG
> + help
> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +   driver. The CMDQ is used to help read/write registers with critical
> +   time limitation, such as updating display configuration during the
> +   vblank.
> +
>  config MTK_INFRACFG
>   bool "MediaTek INFRACFG Support"
>   depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..f7397ef 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile

[Snip...]

> +
> +static int cmdq_eng_get_thread(u64 flag)
> +{
> + if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> + return CMDQ_THR_DISP_MAIN_IDX;
> + else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> + return CMDQ_THR_DISP_SUB_IDX;
> + else
> + return CMDQ_THR_DISP_MISC_IDX;
> +}

I think cmdq should not have knowledge of client. These statement show
that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
the 'session' to replace engine flag. For example, main display create
one cmdq_session and external display create another cmdq_session. For
client driver, every tasks created by main display is bound to main
display session. For cmdq driver, it should dynamically bind a session
to a HW thread, and then dispatch tasks of this session to this HW
thread. After HW thread run out of tasks of this session, detach this
session with this thread.
For the problem of remove wfe cmd, I think a session can have a property
of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
For other client, it's false.

Here is the sample code to create cmdq_rec with session.

merge_wfe_cmd = true;
cmdq_session_create(merge_wfe_cmd, _display_session);
cmdq_rec_create(dev, primary_display_session, );


Therefore, the below definition can be removed.

> +
> +enum cmdq_eng {
> + CMDQ_ENG_DISP_AAL,
> + CMDQ_ENG_DISP_COLOR0,
> + CMDQ_ENG_DISP_COLOR1,
> + CMDQ_ENG_DISP_DPI0,
> + CMDQ_ENG_DISP_DSI0,
> + CMDQ_ENG_DISP_DSI1,
> + CMDQ_ENG_DISP_GAMMA,
> + CMDQ_ENG_DISP_OD,
> + CMDQ_ENG_DISP_OVL0,
> + CMDQ_ENG_DISP_OVL1,
> + CMDQ_ENG_DISP_PWM0,
> + CMDQ_ENG_DISP_PWM1,
> + CMDQ_ENG_DISP_RDMA0,
> + CMDQ_ENG_DISP_RDMA1,
> + CMDQ_ENG_DISP_RDMA2,
> + CMDQ_ENG_DISP_UFOE,
> + CMDQ_ENG_DISP_WDMA0,
> + CMDQ_ENG_DISP_WDMA1,
> + CMDQ_ENG_MAX,
> +};
> +


Regards,
CK



Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-20 Thread CK Hu
Hi, HS:

One comment inline.

On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help read/write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao 
> Signed-off-by: CK Hu 
> ---
>  drivers/soc/mediatek/Kconfig|  10 +
>  drivers/soc/mediatek/Makefile   |   1 +
>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> 
>  include/soc/mediatek/cmdq.h | 197 +
>  4 files changed, 1151 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
>  create mode 100644 include/soc/mediatek/cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index 0a4ea80..c4ad75c 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -1,6 +1,16 @@
>  #
>  # MediaTek SoC drivers
>  #
> +config MTK_CMDQ
> + bool "MediaTek CMDQ Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select MTK_INFRACFG
> + help
> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +   driver. The CMDQ is used to help read/write registers with critical
> +   time limitation, such as updating display configuration during the
> +   vblank.
> +
>  config MTK_INFRACFG
>   bool "MediaTek INFRACFG Support"
>   depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..f7397ef 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile

[Snip...]

> +
> +static int cmdq_eng_get_thread(u64 flag)
> +{
> + if (flag & BIT_ULL(CMDQ_ENG_DISP_DSI0))
> + return CMDQ_THR_DISP_MAIN_IDX;
> + else if (flag & BIT_ULL(CMDQ_ENG_DISP_DPI0))
> + return CMDQ_THR_DISP_SUB_IDX;
> + else
> + return CMDQ_THR_DISP_MISC_IDX;
> +}

I think cmdq should not have knowledge of client. These statement show
that cmdq know that DSI0-tasks is different with DPI0-tasks. I propose
the 'session' to replace engine flag. For example, main display create
one cmdq_session and external display create another cmdq_session. For
client driver, every tasks created by main display is bound to main
display session. For cmdq driver, it should dynamically bind a session
to a HW thread, and then dispatch tasks of this session to this HW
thread. After HW thread run out of tasks of this session, detach this
session with this thread.
For the problem of remove wfe cmd, I think a session can have a property
of merge_wfe_cmd. For display session, session->merge_wfe_cmd = true.
For other client, it's false.

Here is the sample code to create cmdq_rec with session.

merge_wfe_cmd = true;
cmdq_session_create(merge_wfe_cmd, _display_session);
cmdq_rec_create(dev, primary_display_session, );


Therefore, the below definition can be removed.

> +
> +enum cmdq_eng {
> + CMDQ_ENG_DISP_AAL,
> + CMDQ_ENG_DISP_COLOR0,
> + CMDQ_ENG_DISP_COLOR1,
> + CMDQ_ENG_DISP_DPI0,
> + CMDQ_ENG_DISP_DSI0,
> + CMDQ_ENG_DISP_DSI1,
> + CMDQ_ENG_DISP_GAMMA,
> + CMDQ_ENG_DISP_OD,
> + CMDQ_ENG_DISP_OVL0,
> + CMDQ_ENG_DISP_OVL1,
> + CMDQ_ENG_DISP_PWM0,
> + CMDQ_ENG_DISP_PWM1,
> + CMDQ_ENG_DISP_RDMA0,
> + CMDQ_ENG_DISP_RDMA1,
> + CMDQ_ENG_DISP_RDMA2,
> + CMDQ_ENG_DISP_UFOE,
> + CMDQ_ENG_DISP_WDMA0,
> + CMDQ_ENG_DISP_WDMA1,
> + CMDQ_ENG_MAX,
> +};
> +


Regards,
CK



Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-17 Thread Matthias Brugger



On 14/06/16 14:07, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:


On 14/06/16 09:44, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:


On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
   From CPU's point of view, tasks are linked by the busy list.
   From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take releasing tasks into consideration by using the proposed
timer method?
Furthermore, I think the code will become more complex if we also use
timer to implement releasing tasks.



Can't we 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-17 Thread Matthias Brugger



On 14/06/16 14:07, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:


On 14/06/16 09:44, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:


On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
   From CPU's point of view, tasks are linked by the busy list.
   From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take releasing tasks into consideration by using the proposed
timer method?
Furthermore, I think the code will become more complex if we also use
timer to implement releasing tasks.



Can't we 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-17 Thread Matthias Brugger



On 17/06/16 10:28, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:


On 14/06/16 09:44, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:


On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
   From CPU's point of view, tasks are linked by the busy list.
   From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take releasing tasks into consideration by using the proposed
timer method?
Furthermore, I think the code will become 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-17 Thread Matthias Brugger



On 17/06/16 10:28, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:


On 14/06/16 09:44, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:


On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
   From CPU's point of view, tasks are linked by the busy list.
   From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take releasing tasks into consideration by using the proposed
timer method?
Furthermore, I think the code will become 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-17 Thread Horng-Shyang Liao
Hi Matthias,

On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:
> Hi Matthias,
> 
> On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:
> > 
> > On 14/06/16 09:44, Horng-Shyang Liao wrote:
> > > Hi Matthias,
> > >
> > > On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:
> > >>
> > >> On 08/06/16 14:25, Horng-Shyang Liao wrote:
> > >>> Hi Matthias,
> > >>>
> > >>> On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> > 
> >  On 08/06/16 07:40, Horng-Shyang Liao wrote:
> > > Hi Matthias,
> > >
> > > On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> > >>
> > >> On 03/06/16 15:11, Matthias Brugger wrote:
> > >>>
> > >>>
> > >> [...]
> > >>
> >  +
> >  +smp_mb(); /* modify jump before enable thread 
> >  */
> >  +}
> >  +
> >  +cmdq_thread_writel(thread, task->pa_base +
> >  task->command_size,
> >  +   CMDQ_THR_END_ADDR);
> >  +cmdq_thread_resume(thread);
> >  +}
> >  +list_move_tail(>list_entry, 
> >  >task_busy_list);
> >  +spin_unlock_irqrestore(>exec_lock, flags);
> >  +}
> >  +
> >  +static void cmdq_handle_error_done(struct cmdq *cmdq,
> >  +   struct cmdq_thread *thread, u32 
> >  irq_flag)
> >  +{
> >  +struct cmdq_task *task, *tmp, *curr_task = NULL;
> >  +u32 curr_pa;
> >  +struct cmdq_cb_data cmdq_cb_data;
> >  +bool err;
> >  +
> >  +if (irq_flag & CMDQ_THR_IRQ_ERROR)
> >  +err = true;
> >  +else if (irq_flag & CMDQ_THR_IRQ_DONE)
> >  +err = false;
> >  +else
> >  +return;
> >  +
> >  +curr_pa = cmdq_thread_readl(thread, 
> >  CMDQ_THR_CURR_ADDR);
> >  +
> >  +list_for_each_entry_safe(task, tmp, 
> >  >task_busy_list,
> >  + list_entry) {
> >  +if (curr_pa >= task->pa_base &&
> >  +curr_pa < (task->pa_base + 
> >  task->command_size))
> > >>>
> > >>> What are you checking here? It seems as if you make some 
> > >>> implcit
> > >>> assumptions about pa_base and the order of execution of
> > >>> commands in the
> > >>> thread. Is it save to do so? Does dma_alloc_coherent give 
> > >>> any
> > >>> guarantees
> > >>> about dma_handle?
> > >>
> > >> 1. Check what is the current running task in this GCE thread.
> > >> 2. Yes.
> > >> 3. Yes, CMDQ doesn't use iommu, so physical address is 
> > >> continuous.
> > >>
> > >
> > > Yes, physical addresses might be continous, but AFAIK there 
> > > is no
> > > guarantee that the dma_handle address is steadily growing, 
> > > when
> > > calling
> > > dma_alloc_coherent. And if I understand the code correctly, 
> > > you
> > > use this
> > > assumption to decide if the task picked from task_busy_list is
> > > currently
> > > executing. So I think this mecanism is not working.
> > 
> >  I don't use dma_handle address, and just use physical 
> >  addresses.
> >    From CPU's point of view, tasks are linked by the busy 
> >  list.
> >    From GCE's point of view, tasks are linked by the JUMP 
> >  command.
> > 
> > > In which cases does the HW thread raise an interrupt.
> > > In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> > 
> >  GCE will raise interrupt if any task is done or error.
> >  However, GCE is fast, so CPU may get multiple done tasks
> >  when it is running ISR.
> > 
> >  In case of error, that GCE thread will pause and raise 
> >  interrupt.
> >  So, CPU may get multiple done tasks and one error task.
> > 
> > >>>
> > >>> I think we should reimplement the ISR mechanism. Can't we just 
> > >>> read
> > >>> CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
> > >>> cmdq_handle_error_done to the thread_fn? You will need to pass
> > >>> information from 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-17 Thread Horng-Shyang Liao
Hi Matthias,

On Tue, 2016-06-14 at 20:07 +0800, Horng-Shyang Liao wrote:
> Hi Matthias,
> 
> On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:
> > 
> > On 14/06/16 09:44, Horng-Shyang Liao wrote:
> > > Hi Matthias,
> > >
> > > On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:
> > >>
> > >> On 08/06/16 14:25, Horng-Shyang Liao wrote:
> > >>> Hi Matthias,
> > >>>
> > >>> On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> > 
> >  On 08/06/16 07:40, Horng-Shyang Liao wrote:
> > > Hi Matthias,
> > >
> > > On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> > >>
> > >> On 03/06/16 15:11, Matthias Brugger wrote:
> > >>>
> > >>>
> > >> [...]
> > >>
> >  +
> >  +smp_mb(); /* modify jump before enable thread 
> >  */
> >  +}
> >  +
> >  +cmdq_thread_writel(thread, task->pa_base +
> >  task->command_size,
> >  +   CMDQ_THR_END_ADDR);
> >  +cmdq_thread_resume(thread);
> >  +}
> >  +list_move_tail(>list_entry, 
> >  >task_busy_list);
> >  +spin_unlock_irqrestore(>exec_lock, flags);
> >  +}
> >  +
> >  +static void cmdq_handle_error_done(struct cmdq *cmdq,
> >  +   struct cmdq_thread *thread, u32 
> >  irq_flag)
> >  +{
> >  +struct cmdq_task *task, *tmp, *curr_task = NULL;
> >  +u32 curr_pa;
> >  +struct cmdq_cb_data cmdq_cb_data;
> >  +bool err;
> >  +
> >  +if (irq_flag & CMDQ_THR_IRQ_ERROR)
> >  +err = true;
> >  +else if (irq_flag & CMDQ_THR_IRQ_DONE)
> >  +err = false;
> >  +else
> >  +return;
> >  +
> >  +curr_pa = cmdq_thread_readl(thread, 
> >  CMDQ_THR_CURR_ADDR);
> >  +
> >  +list_for_each_entry_safe(task, tmp, 
> >  >task_busy_list,
> >  + list_entry) {
> >  +if (curr_pa >= task->pa_base &&
> >  +curr_pa < (task->pa_base + 
> >  task->command_size))
> > >>>
> > >>> What are you checking here? It seems as if you make some 
> > >>> implcit
> > >>> assumptions about pa_base and the order of execution of
> > >>> commands in the
> > >>> thread. Is it save to do so? Does dma_alloc_coherent give 
> > >>> any
> > >>> guarantees
> > >>> about dma_handle?
> > >>
> > >> 1. Check what is the current running task in this GCE thread.
> > >> 2. Yes.
> > >> 3. Yes, CMDQ doesn't use iommu, so physical address is 
> > >> continuous.
> > >>
> > >
> > > Yes, physical addresses might be continous, but AFAIK there 
> > > is no
> > > guarantee that the dma_handle address is steadily growing, 
> > > when
> > > calling
> > > dma_alloc_coherent. And if I understand the code correctly, 
> > > you
> > > use this
> > > assumption to decide if the task picked from task_busy_list is
> > > currently
> > > executing. So I think this mecanism is not working.
> > 
> >  I don't use dma_handle address, and just use physical 
> >  addresses.
> >    From CPU's point of view, tasks are linked by the busy 
> >  list.
> >    From GCE's point of view, tasks are linked by the JUMP 
> >  command.
> > 
> > > In which cases does the HW thread raise an interrupt.
> > > In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> > 
> >  GCE will raise interrupt if any task is done or error.
> >  However, GCE is fast, so CPU may get multiple done tasks
> >  when it is running ISR.
> > 
> >  In case of error, that GCE thread will pause and raise 
> >  interrupt.
> >  So, CPU may get multiple done tasks and one error task.
> > 
> > >>>
> > >>> I think we should reimplement the ISR mechanism. Can't we just 
> > >>> read
> > >>> CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
> > >>> cmdq_handle_error_done to the thread_fn? You will need to pass
> > >>> information from 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-14 Thread Horng-Shyang Liao
Hi Matthias,

On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:
> 
> On 14/06/16 09:44, Horng-Shyang Liao wrote:
> > Hi Matthias,
> >
> > On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:
> >>
> >> On 08/06/16 14:25, Horng-Shyang Liao wrote:
> >>> Hi Matthias,
> >>>
> >>> On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> 
>  On 08/06/16 07:40, Horng-Shyang Liao wrote:
> > Hi Matthias,
> >
> > On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> >>
> >> On 03/06/16 15:11, Matthias Brugger wrote:
> >>>
> >>>
> >> [...]
> >>
>  +
>  +smp_mb(); /* modify jump before enable thread */
>  +}
>  +
>  +cmdq_thread_writel(thread, task->pa_base +
>  task->command_size,
>  +   CMDQ_THR_END_ADDR);
>  +cmdq_thread_resume(thread);
>  +}
>  +list_move_tail(>list_entry, 
>  >task_busy_list);
>  +spin_unlock_irqrestore(>exec_lock, flags);
>  +}
>  +
>  +static void cmdq_handle_error_done(struct cmdq *cmdq,
>  +   struct cmdq_thread *thread, u32 irq_flag)
>  +{
>  +struct cmdq_task *task, *tmp, *curr_task = NULL;
>  +u32 curr_pa;
>  +struct cmdq_cb_data cmdq_cb_data;
>  +bool err;
>  +
>  +if (irq_flag & CMDQ_THR_IRQ_ERROR)
>  +err = true;
>  +else if (irq_flag & CMDQ_THR_IRQ_DONE)
>  +err = false;
>  +else
>  +return;
>  +
>  +curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
>  +
>  +list_for_each_entry_safe(task, tmp, 
>  >task_busy_list,
>  + list_entry) {
>  +if (curr_pa >= task->pa_base &&
>  +curr_pa < (task->pa_base + task->command_size))
> >>>
> >>> What are you checking here? It seems as if you make some 
> >>> implcit
> >>> assumptions about pa_base and the order of execution of
> >>> commands in the
> >>> thread. Is it save to do so? Does dma_alloc_coherent give any
> >>> guarantees
> >>> about dma_handle?
> >>
> >> 1. Check what is the current running task in this GCE thread.
> >> 2. Yes.
> >> 3. Yes, CMDQ doesn't use iommu, so physical address is 
> >> continuous.
> >>
> >
> > Yes, physical addresses might be continous, but AFAIK there is 
> > no
> > guarantee that the dma_handle address is steadily growing, when
> > calling
> > dma_alloc_coherent. And if I understand the code correctly, you
> > use this
> > assumption to decide if the task picked from task_busy_list is
> > currently
> > executing. So I think this mecanism is not working.
> 
>  I don't use dma_handle address, and just use physical addresses.
>    From CPU's point of view, tasks are linked by the busy 
>  list.
>    From GCE's point of view, tasks are linked by the JUMP 
>  command.
> 
> > In which cases does the HW thread raise an interrupt.
> > In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> 
>  GCE will raise interrupt if any task is done or error.
>  However, GCE is fast, so CPU may get multiple done tasks
>  when it is running ISR.
> 
>  In case of error, that GCE thread will pause and raise interrupt.
>  So, CPU may get multiple done tasks and one error task.
> 
> >>>
> >>> I think we should reimplement the ISR mechanism. Can't we just 
> >>> read
> >>> CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
> >>> cmdq_handle_error_done to the thread_fn? You will need to pass
> >>> information from the handler to thread_fn, but that shouldn't be 
> >>> an
> >>> issue. AFAIK interrupts are disabled in the handler, so we should 
> >>> stay
> >>> there as short as possible. Traversing task_busy_list is 
> >>> expensive, so
> >>> we need to do it in a thread context.
> >>
> >> Actually, our initial implementation is similar to your suggestion,
> >> but display needs CMDQ to return callback 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-14 Thread Horng-Shyang Liao
Hi Matthias,

On Tue, 2016-06-14 at 12:17 +0200, Matthias Brugger wrote:
> 
> On 14/06/16 09:44, Horng-Shyang Liao wrote:
> > Hi Matthias,
> >
> > On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:
> >>
> >> On 08/06/16 14:25, Horng-Shyang Liao wrote:
> >>> Hi Matthias,
> >>>
> >>> On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> 
>  On 08/06/16 07:40, Horng-Shyang Liao wrote:
> > Hi Matthias,
> >
> > On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> >>
> >> On 03/06/16 15:11, Matthias Brugger wrote:
> >>>
> >>>
> >> [...]
> >>
>  +
>  +smp_mb(); /* modify jump before enable thread */
>  +}
>  +
>  +cmdq_thread_writel(thread, task->pa_base +
>  task->command_size,
>  +   CMDQ_THR_END_ADDR);
>  +cmdq_thread_resume(thread);
>  +}
>  +list_move_tail(>list_entry, 
>  >task_busy_list);
>  +spin_unlock_irqrestore(>exec_lock, flags);
>  +}
>  +
>  +static void cmdq_handle_error_done(struct cmdq *cmdq,
>  +   struct cmdq_thread *thread, u32 irq_flag)
>  +{
>  +struct cmdq_task *task, *tmp, *curr_task = NULL;
>  +u32 curr_pa;
>  +struct cmdq_cb_data cmdq_cb_data;
>  +bool err;
>  +
>  +if (irq_flag & CMDQ_THR_IRQ_ERROR)
>  +err = true;
>  +else if (irq_flag & CMDQ_THR_IRQ_DONE)
>  +err = false;
>  +else
>  +return;
>  +
>  +curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
>  +
>  +list_for_each_entry_safe(task, tmp, 
>  >task_busy_list,
>  + list_entry) {
>  +if (curr_pa >= task->pa_base &&
>  +curr_pa < (task->pa_base + task->command_size))
> >>>
> >>> What are you checking here? It seems as if you make some 
> >>> implcit
> >>> assumptions about pa_base and the order of execution of
> >>> commands in the
> >>> thread. Is it save to do so? Does dma_alloc_coherent give any
> >>> guarantees
> >>> about dma_handle?
> >>
> >> 1. Check what is the current running task in this GCE thread.
> >> 2. Yes.
> >> 3. Yes, CMDQ doesn't use iommu, so physical address is 
> >> continuous.
> >>
> >
> > Yes, physical addresses might be continous, but AFAIK there is 
> > no
> > guarantee that the dma_handle address is steadily growing, when
> > calling
> > dma_alloc_coherent. And if I understand the code correctly, you
> > use this
> > assumption to decide if the task picked from task_busy_list is
> > currently
> > executing. So I think this mecanism is not working.
> 
>  I don't use dma_handle address, and just use physical addresses.
>    From CPU's point of view, tasks are linked by the busy 
>  list.
>    From GCE's point of view, tasks are linked by the JUMP 
>  command.
> 
> > In which cases does the HW thread raise an interrupt.
> > In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> 
>  GCE will raise interrupt if any task is done or error.
>  However, GCE is fast, so CPU may get multiple done tasks
>  when it is running ISR.
> 
>  In case of error, that GCE thread will pause and raise interrupt.
>  So, CPU may get multiple done tasks and one error task.
> 
> >>>
> >>> I think we should reimplement the ISR mechanism. Can't we just 
> >>> read
> >>> CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
> >>> cmdq_handle_error_done to the thread_fn? You will need to pass
> >>> information from the handler to thread_fn, but that shouldn't be 
> >>> an
> >>> issue. AFAIK interrupts are disabled in the handler, so we should 
> >>> stay
> >>> there as short as possible. Traversing task_busy_list is 
> >>> expensive, so
> >>> we need to do it in a thread context.
> >>
> >> Actually, our initial implementation is similar to your suggestion,
> >> but display needs CMDQ to return callback 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-14 Thread Matthias Brugger



On 14/06/16 09:44, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:


On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
  From CPU's point of view, tasks are linked by the busy list.
  From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


   From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take releasing tasks into consideration by using the proposed
timer method?
Furthermore, I think the code will become more complex if we also use
timer to implement releasing tasks.



Can't we call
   clk_disable_unprepare(cmdq->clock);
   cmdq_task_release(task);
after invoking the callback?


Do you 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-14 Thread Matthias Brugger



On 14/06/16 09:44, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:


On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
  From CPU's point of view, tasks are linked by the busy list.
  From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


   From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take releasing tasks into consideration by using the proposed
timer method?
Furthermore, I think the code will become more complex if we also use
timer to implement releasing tasks.



Can't we call
   clk_disable_unprepare(cmdq->clock);
   cmdq_task_release(task);
after invoking the callback?


Do you 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-14 Thread Horng-Shyang Liao
Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:
> 
> On 08/06/16 14:25, Horng-Shyang Liao wrote:
> > Hi Matthias,
> >
> > On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> >>
> >> On 08/06/16 07:40, Horng-Shyang Liao wrote:
> >>> Hi Matthias,
> >>>
> >>> On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> 
>  On 03/06/16 15:11, Matthias Brugger wrote:
> >
> >
>  [...]
> 
> >> +
> >> +smp_mb(); /* modify jump before enable thread */
> >> +}
> >> +
> >> +cmdq_thread_writel(thread, task->pa_base +
> >> task->command_size,
> >> +   CMDQ_THR_END_ADDR);
> >> +cmdq_thread_resume(thread);
> >> +}
> >> +list_move_tail(>list_entry, 
> >> >task_busy_list);
> >> +spin_unlock_irqrestore(>exec_lock, flags);
> >> +}
> >> +
> >> +static void cmdq_handle_error_done(struct cmdq *cmdq,
> >> +   struct cmdq_thread *thread, u32 irq_flag)
> >> +{
> >> +struct cmdq_task *task, *tmp, *curr_task = NULL;
> >> +u32 curr_pa;
> >> +struct cmdq_cb_data cmdq_cb_data;
> >> +bool err;
> >> +
> >> +if (irq_flag & CMDQ_THR_IRQ_ERROR)
> >> +err = true;
> >> +else if (irq_flag & CMDQ_THR_IRQ_DONE)
> >> +err = false;
> >> +else
> >> +return;
> >> +
> >> +curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
> >> +
> >> +list_for_each_entry_safe(task, tmp, 
> >> >task_busy_list,
> >> + list_entry) {
> >> +if (curr_pa >= task->pa_base &&
> >> +curr_pa < (task->pa_base + task->command_size))
> >
> > What are you checking here? It seems as if you make some implcit
> > assumptions about pa_base and the order of execution of
> > commands in the
> > thread. Is it save to do so? Does dma_alloc_coherent give any
> > guarantees
> > about dma_handle?
> 
>  1. Check what is the current running task in this GCE thread.
>  2. Yes.
>  3. Yes, CMDQ doesn't use iommu, so physical address is 
>  continuous.
> 
> >>>
> >>> Yes, physical addresses might be continous, but AFAIK there is no
> >>> guarantee that the dma_handle address is steadily growing, when
> >>> calling
> >>> dma_alloc_coherent. And if I understand the code correctly, you
> >>> use this
> >>> assumption to decide if the task picked from task_busy_list is
> >>> currently
> >>> executing. So I think this mecanism is not working.
> >>
> >> I don't use dma_handle address, and just use physical addresses.
> >>  From CPU's point of view, tasks are linked by the busy list.
> >>  From GCE's point of view, tasks are linked by the JUMP 
> >> command.
> >>
> >>> In which cases does the HW thread raise an interrupt.
> >>> In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> >>
> >> GCE will raise interrupt if any task is done or error.
> >> However, GCE is fast, so CPU may get multiple done tasks
> >> when it is running ISR.
> >>
> >> In case of error, that GCE thread will pause and raise interrupt.
> >> So, CPU may get multiple done tasks and one error task.
> >>
> >
> > I think we should reimplement the ISR mechanism. Can't we just read
> > CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
> > cmdq_handle_error_done to the thread_fn? You will need to pass
> > information from the handler to thread_fn, but that shouldn't be an
> > issue. AFAIK interrupts are disabled in the handler, so we should 
> > stay
> > there as short as possible. Traversing task_busy_list is expensive, 
> > so
> > we need to do it in a thread context.
> 
>  Actually, our initial implementation is similar to your suggestion,
>  but display needs CMDQ to return callback function very precisely,
>  else display will drop frame.
>  For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
>  and CMDQ needs to call callback function in ISR.
>  If we defer callback to workqueue, the time interval may be larger 
>  than
>  32 ms.sometimes.
> 
> >>>
> >>> I think the problem is, that you implemented the workqueue as a 
> >>> 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-14 Thread Horng-Shyang Liao
Hi Matthias,

On Wed, 2016-06-08 at 17:35 +0200, Matthias Brugger wrote:
> 
> On 08/06/16 14:25, Horng-Shyang Liao wrote:
> > Hi Matthias,
> >
> > On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> >>
> >> On 08/06/16 07:40, Horng-Shyang Liao wrote:
> >>> Hi Matthias,
> >>>
> >>> On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> 
>  On 03/06/16 15:11, Matthias Brugger wrote:
> >
> >
>  [...]
> 
> >> +
> >> +smp_mb(); /* modify jump before enable thread */
> >> +}
> >> +
> >> +cmdq_thread_writel(thread, task->pa_base +
> >> task->command_size,
> >> +   CMDQ_THR_END_ADDR);
> >> +cmdq_thread_resume(thread);
> >> +}
> >> +list_move_tail(>list_entry, 
> >> >task_busy_list);
> >> +spin_unlock_irqrestore(>exec_lock, flags);
> >> +}
> >> +
> >> +static void cmdq_handle_error_done(struct cmdq *cmdq,
> >> +   struct cmdq_thread *thread, u32 irq_flag)
> >> +{
> >> +struct cmdq_task *task, *tmp, *curr_task = NULL;
> >> +u32 curr_pa;
> >> +struct cmdq_cb_data cmdq_cb_data;
> >> +bool err;
> >> +
> >> +if (irq_flag & CMDQ_THR_IRQ_ERROR)
> >> +err = true;
> >> +else if (irq_flag & CMDQ_THR_IRQ_DONE)
> >> +err = false;
> >> +else
> >> +return;
> >> +
> >> +curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
> >> +
> >> +list_for_each_entry_safe(task, tmp, 
> >> >task_busy_list,
> >> + list_entry) {
> >> +if (curr_pa >= task->pa_base &&
> >> +curr_pa < (task->pa_base + task->command_size))
> >
> > What are you checking here? It seems as if you make some implcit
> > assumptions about pa_base and the order of execution of
> > commands in the
> > thread. Is it save to do so? Does dma_alloc_coherent give any
> > guarantees
> > about dma_handle?
> 
>  1. Check what is the current running task in this GCE thread.
>  2. Yes.
>  3. Yes, CMDQ doesn't use iommu, so physical address is 
>  continuous.
> 
> >>>
> >>> Yes, physical addresses might be continous, but AFAIK there is no
> >>> guarantee that the dma_handle address is steadily growing, when
> >>> calling
> >>> dma_alloc_coherent. And if I understand the code correctly, you
> >>> use this
> >>> assumption to decide if the task picked from task_busy_list is
> >>> currently
> >>> executing. So I think this mecanism is not working.
> >>
> >> I don't use dma_handle address, and just use physical addresses.
> >>  From CPU's point of view, tasks are linked by the busy list.
> >>  From GCE's point of view, tasks are linked by the JUMP 
> >> command.
> >>
> >>> In which cases does the HW thread raise an interrupt.
> >>> In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> >>
> >> GCE will raise interrupt if any task is done or error.
> >> However, GCE is fast, so CPU may get multiple done tasks
> >> when it is running ISR.
> >>
> >> In case of error, that GCE thread will pause and raise interrupt.
> >> So, CPU may get multiple done tasks and one error task.
> >>
> >
> > I think we should reimplement the ISR mechanism. Can't we just read
> > CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
> > cmdq_handle_error_done to the thread_fn? You will need to pass
> > information from the handler to thread_fn, but that shouldn't be an
> > issue. AFAIK interrupts are disabled in the handler, so we should 
> > stay
> > there as short as possible. Traversing task_busy_list is expensive, 
> > so
> > we need to do it in a thread context.
> 
>  Actually, our initial implementation is similar to your suggestion,
>  but display needs CMDQ to return callback function very precisely,
>  else display will drop frame.
>  For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
>  and CMDQ needs to call callback function in ISR.
>  If we defer callback to workqueue, the time interval may be larger 
>  than
>  32 ms.sometimes.
> 
> >>>
> >>> I think the problem is, that you implemented the workqueue as a 
> >>> 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-08 Thread Matthias Brugger



On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
 From CPU's point of view, tasks are linked by the busy list.
 From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


  From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take releasing tasks into consideration by using the proposed
timer method?
Furthermore, I think the code will become more complex if we also use
timer to implement releasing tasks.



Can't we call
  clk_disable_unprepare(cmdq->clock);
  cmdq_task_release(task);
after invoking the callback?


Do you mean just call these two functions in ISR?
My major concern is dma_free_coherent() and kfree() in
cmdq_task_release(task).



Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-08 Thread Matthias Brugger



On 08/06/16 14:25, Horng-Shyang Liao wrote:

Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:


On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
 From CPU's point of view, tasks are linked by the busy list.
 From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


  From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take releasing tasks into consideration by using the proposed
timer method?
Furthermore, I think the code will become more complex if we also use
timer to implement releasing tasks.



Can't we call
  clk_disable_unprepare(cmdq->clock);
  cmdq_task_release(task);
after invoking the callback?


Do you mean just call these two functions in ISR?
My major concern is dma_free_coherent() and kfree() in
cmdq_task_release(task).



Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-08 Thread Horng-Shyang Liao
Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> 
> On 08/06/16 07:40, Horng-Shyang Liao wrote:
> > Hi Matthias,
> >
> > On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> >>
> >> On 03/06/16 15:11, Matthias Brugger wrote:
> >>>
> >>>
> >> [...]
> >>
>  +
>  +smp_mb(); /* modify jump before enable thread */
>  +}
>  +
>  +cmdq_thread_writel(thread, task->pa_base +
>  task->command_size,
>  +   CMDQ_THR_END_ADDR);
>  +cmdq_thread_resume(thread);
>  +}
>  +list_move_tail(>list_entry, >task_busy_list);
>  +spin_unlock_irqrestore(>exec_lock, flags);
>  +}
>  +
>  +static void cmdq_handle_error_done(struct cmdq *cmdq,
>  +   struct cmdq_thread *thread, u32 irq_flag)
>  +{
>  +struct cmdq_task *task, *tmp, *curr_task = NULL;
>  +u32 curr_pa;
>  +struct cmdq_cb_data cmdq_cb_data;
>  +bool err;
>  +
>  +if (irq_flag & CMDQ_THR_IRQ_ERROR)
>  +err = true;
>  +else if (irq_flag & CMDQ_THR_IRQ_DONE)
>  +err = false;
>  +else
>  +return;
>  +
>  +curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
>  +
>  +list_for_each_entry_safe(task, tmp, >task_busy_list,
>  + list_entry) {
>  +if (curr_pa >= task->pa_base &&
>  +curr_pa < (task->pa_base + task->command_size))
> >>>
> >>> What are you checking here? It seems as if you make some implcit
> >>> assumptions about pa_base and the order of execution of
> >>> commands in the
> >>> thread. Is it save to do so? Does dma_alloc_coherent give any
> >>> guarantees
> >>> about dma_handle?
> >>
> >> 1. Check what is the current running task in this GCE thread.
> >> 2. Yes.
> >> 3. Yes, CMDQ doesn't use iommu, so physical address is continuous.
> >>
> >
> > Yes, physical addresses might be continous, but AFAIK there is no
> > guarantee that the dma_handle address is steadily growing, when
> > calling
> > dma_alloc_coherent. And if I understand the code correctly, you
> > use this
> > assumption to decide if the task picked from task_busy_list is
> > currently
> > executing. So I think this mecanism is not working.
> 
>  I don't use dma_handle address, and just use physical addresses.
>  From CPU's point of view, tasks are linked by the busy list.
>  From GCE's point of view, tasks are linked by the JUMP command.
> 
> > In which cases does the HW thread raise an interrupt.
> > In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> 
>  GCE will raise interrupt if any task is done or error.
>  However, GCE is fast, so CPU may get multiple done tasks
>  when it is running ISR.
> 
>  In case of error, that GCE thread will pause and raise interrupt.
>  So, CPU may get multiple done tasks and one error task.
> 
> >>>
> >>> I think we should reimplement the ISR mechanism. Can't we just read
> >>> CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
> >>> cmdq_handle_error_done to the thread_fn? You will need to pass
> >>> information from the handler to thread_fn, but that shouldn't be an
> >>> issue. AFAIK interrupts are disabled in the handler, so we should stay
> >>> there as short as possible. Traversing task_busy_list is expensive, so
> >>> we need to do it in a thread context.
> >>
> >> Actually, our initial implementation is similar to your suggestion,
> >> but display needs CMDQ to return callback function very precisely,
> >> else display will drop frame.
> >> For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
> >> and CMDQ needs to call callback function in ISR.
> >> If we defer callback to workqueue, the time interval may be larger than
> >> 32 ms.sometimes.
> >>
> >
> > I think the problem is, that you implemented the workqueue as a ordered
> > workqueue, so there is no parallel processing. I'm still not sure why
> > you need the workqueue to be ordered. Can you please explain.
> 
>  The order should be kept.
>  Let me use mouse cursor as an example.
>  If task 1 means move mouse cursor to point A, task 2 means point B,
>  and task 3 means point C, our expected result is A -> B -> C.
>  If the order is not kept, the result could become A -> C -> 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-08 Thread Horng-Shyang Liao
Hi Matthias,

On Wed, 2016-06-08 at 12:45 +0200, Matthias Brugger wrote:
> 
> On 08/06/16 07:40, Horng-Shyang Liao wrote:
> > Hi Matthias,
> >
> > On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> >>
> >> On 03/06/16 15:11, Matthias Brugger wrote:
> >>>
> >>>
> >> [...]
> >>
>  +
>  +smp_mb(); /* modify jump before enable thread */
>  +}
>  +
>  +cmdq_thread_writel(thread, task->pa_base +
>  task->command_size,
>  +   CMDQ_THR_END_ADDR);
>  +cmdq_thread_resume(thread);
>  +}
>  +list_move_tail(>list_entry, >task_busy_list);
>  +spin_unlock_irqrestore(>exec_lock, flags);
>  +}
>  +
>  +static void cmdq_handle_error_done(struct cmdq *cmdq,
>  +   struct cmdq_thread *thread, u32 irq_flag)
>  +{
>  +struct cmdq_task *task, *tmp, *curr_task = NULL;
>  +u32 curr_pa;
>  +struct cmdq_cb_data cmdq_cb_data;
>  +bool err;
>  +
>  +if (irq_flag & CMDQ_THR_IRQ_ERROR)
>  +err = true;
>  +else if (irq_flag & CMDQ_THR_IRQ_DONE)
>  +err = false;
>  +else
>  +return;
>  +
>  +curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
>  +
>  +list_for_each_entry_safe(task, tmp, >task_busy_list,
>  + list_entry) {
>  +if (curr_pa >= task->pa_base &&
>  +curr_pa < (task->pa_base + task->command_size))
> >>>
> >>> What are you checking here? It seems as if you make some implcit
> >>> assumptions about pa_base and the order of execution of
> >>> commands in the
> >>> thread. Is it save to do so? Does dma_alloc_coherent give any
> >>> guarantees
> >>> about dma_handle?
> >>
> >> 1. Check what is the current running task in this GCE thread.
> >> 2. Yes.
> >> 3. Yes, CMDQ doesn't use iommu, so physical address is continuous.
> >>
> >
> > Yes, physical addresses might be continous, but AFAIK there is no
> > guarantee that the dma_handle address is steadily growing, when
> > calling
> > dma_alloc_coherent. And if I understand the code correctly, you
> > use this
> > assumption to decide if the task picked from task_busy_list is
> > currently
> > executing. So I think this mecanism is not working.
> 
>  I don't use dma_handle address, and just use physical addresses.
>  From CPU's point of view, tasks are linked by the busy list.
>  From GCE's point of view, tasks are linked by the JUMP command.
> 
> > In which cases does the HW thread raise an interrupt.
> > In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> 
>  GCE will raise interrupt if any task is done or error.
>  However, GCE is fast, so CPU may get multiple done tasks
>  when it is running ISR.
> 
>  In case of error, that GCE thread will pause and raise interrupt.
>  So, CPU may get multiple done tasks and one error task.
> 
> >>>
> >>> I think we should reimplement the ISR mechanism. Can't we just read
> >>> CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
> >>> cmdq_handle_error_done to the thread_fn? You will need to pass
> >>> information from the handler to thread_fn, but that shouldn't be an
> >>> issue. AFAIK interrupts are disabled in the handler, so we should stay
> >>> there as short as possible. Traversing task_busy_list is expensive, so
> >>> we need to do it in a thread context.
> >>
> >> Actually, our initial implementation is similar to your suggestion,
> >> but display needs CMDQ to return callback function very precisely,
> >> else display will drop frame.
> >> For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
> >> and CMDQ needs to call callback function in ISR.
> >> If we defer callback to workqueue, the time interval may be larger than
> >> 32 ms.sometimes.
> >>
> >
> > I think the problem is, that you implemented the workqueue as a ordered
> > workqueue, so there is no parallel processing. I'm still not sure why
> > you need the workqueue to be ordered. Can you please explain.
> 
>  The order should be kept.
>  Let me use mouse cursor as an example.
>  If task 1 means move mouse cursor to point A, task 2 means point B,
>  and task 3 means point C, our expected result is A -> B -> C.
>  If the order is not kept, the result could become A -> C -> 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-08 Thread Matthias Brugger



On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
From CPU's point of view, tasks are linked by the busy list.
From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


 From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take releasing tasks into consideration by using the proposed
timer method?
Furthermore, I think the code will become more complex if we also use
timer to implement releasing tasks.



Can't we call
clk_disable_unprepare(cmdq->clock);
cmdq_task_release(task);
after invoking the callback?
Regrading the clock, wouldn't it be easier to handle the clock 
enable/disable depending on the state of task_busy_list? I suppose we 
can't as we would need to check the task_busy_list of all threads, right?


Regards,
Matthias


Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-08 Thread Matthias Brugger



On 08/06/16 07:40, Horng-Shyang Liao wrote:

Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:


On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
From CPU's point of view, tasks are linked by the busy list.
From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets
programmed to the time a timeout in the first task in the busy list
would happen. Everytime we update the busy list (e.g. because of task
got finished by the thread), we update the timer. When the timer
triggers, which hopefully won't happen too often, we return timeout on
the busy list elements, until the time is lower then the actual time.

At least with this we can reduce the data structures in this driver and
make it more lightweight.


 From my understanding, your proposed method can handle timeout case.

However, the workqueue is also in charge of releasing tasks.
Do you take releasing tasks into consideration by using the proposed
timer method?
Furthermore, I think the code will become more complex if we also use
timer to implement releasing tasks.



Can't we call
clk_disable_unprepare(cmdq->clock);
cmdq_task_release(task);
after invoking the callback?
Regrading the clock, wouldn't it be easier to handle the clock 
enable/disable depending on the state of task_busy_list? I suppose we 
can't as we would need to check the task_busy_list of all threads, right?


Regards,
Matthias


Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-07 Thread Horng-Shyang Liao
Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> 
> On 03/06/16 15:11, Matthias Brugger wrote:
> >
> >
> [...]
> 
> >> +
> >> +smp_mb(); /* modify jump before enable thread */
> >> +}
> >> +
> >> +cmdq_thread_writel(thread, task->pa_base +
> >> task->command_size,
> >> +   CMDQ_THR_END_ADDR);
> >> +cmdq_thread_resume(thread);
> >> +}
> >> +list_move_tail(>list_entry, >task_busy_list);
> >> +spin_unlock_irqrestore(>exec_lock, flags);
> >> +}
> >> +
> >> +static void cmdq_handle_error_done(struct cmdq *cmdq,
> >> +   struct cmdq_thread *thread, u32 irq_flag)
> >> +{
> >> +struct cmdq_task *task, *tmp, *curr_task = NULL;
> >> +u32 curr_pa;
> >> +struct cmdq_cb_data cmdq_cb_data;
> >> +bool err;
> >> +
> >> +if (irq_flag & CMDQ_THR_IRQ_ERROR)
> >> +err = true;
> >> +else if (irq_flag & CMDQ_THR_IRQ_DONE)
> >> +err = false;
> >> +else
> >> +return;
> >> +
> >> +curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
> >> +
> >> +list_for_each_entry_safe(task, tmp, >task_busy_list,
> >> + list_entry) {
> >> +if (curr_pa >= task->pa_base &&
> >> +curr_pa < (task->pa_base + task->command_size))
> >
> > What are you checking here? It seems as if you make some implcit
> > assumptions about pa_base and the order of execution of
> > commands in the
> > thread. Is it save to do so? Does dma_alloc_coherent give any
> > guarantees
> > about dma_handle?
> 
>  1. Check what is the current running task in this GCE thread.
>  2. Yes.
>  3. Yes, CMDQ doesn't use iommu, so physical address is continuous.
> 
> >>>
> >>> Yes, physical addresses might be continous, but AFAIK there is no
> >>> guarantee that the dma_handle address is steadily growing, when
> >>> calling
> >>> dma_alloc_coherent. And if I understand the code correctly, you
> >>> use this
> >>> assumption to decide if the task picked from task_busy_list is
> >>> currently
> >>> executing. So I think this mecanism is not working.
> >>
> >> I don't use dma_handle address, and just use physical addresses.
> >>From CPU's point of view, tasks are linked by the busy list.
> >>From GCE's point of view, tasks are linked by the JUMP command.
> >>
> >>> In which cases does the HW thread raise an interrupt.
> >>> In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> >>
> >> GCE will raise interrupt if any task is done or error.
> >> However, GCE is fast, so CPU may get multiple done tasks
> >> when it is running ISR.
> >>
> >> In case of error, that GCE thread will pause and raise interrupt.
> >> So, CPU may get multiple done tasks and one error task.
> >>
> >
> > I think we should reimplement the ISR mechanism. Can't we just read
> > CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
> > cmdq_handle_error_done to the thread_fn? You will need to pass
> > information from the handler to thread_fn, but that shouldn't be an
> > issue. AFAIK interrupts are disabled in the handler, so we should stay
> > there as short as possible. Traversing task_busy_list is expensive, so
> > we need to do it in a thread context.
> 
>  Actually, our initial implementation is similar to your suggestion,
>  but display needs CMDQ to return callback function very precisely,
>  else display will drop frame.
>  For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
>  and CMDQ needs to call callback function in ISR.
>  If we defer callback to workqueue, the time interval may be larger than
>  32 ms.sometimes.
> 
> >>>
> >>> I think the problem is, that you implemented the workqueue as a ordered
> >>> workqueue, so there is no parallel processing. I'm still not sure why
> >>> you need the workqueue to be ordered. Can you please explain.
> >>
> >> The order should be kept.
> >> Let me use mouse cursor as an example.
> >> If task 1 means move mouse cursor to point A, task 2 means point B,
> >> and task 3 means point C, our expected result is A -> B -> C.
> >> If the order is not kept, the result could become A -> C -> B.
> >>
> >
> > Got it, thanks for the clarification.
> >
> 
> I think a way to get rid of the workqueue is to use a timer, which gets 
> programmed to the time a timeout in the first task in the busy list 
> would happen. Everytime we update the busy list (e.g. because of task 
> got finished by the thread), we update the timer. When the 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-07 Thread Horng-Shyang Liao
Hi Matthias,

On Tue, 2016-06-07 at 18:59 +0200, Matthias Brugger wrote:
> 
> On 03/06/16 15:11, Matthias Brugger wrote:
> >
> >
> [...]
> 
> >> +
> >> +smp_mb(); /* modify jump before enable thread */
> >> +}
> >> +
> >> +cmdq_thread_writel(thread, task->pa_base +
> >> task->command_size,
> >> +   CMDQ_THR_END_ADDR);
> >> +cmdq_thread_resume(thread);
> >> +}
> >> +list_move_tail(>list_entry, >task_busy_list);
> >> +spin_unlock_irqrestore(>exec_lock, flags);
> >> +}
> >> +
> >> +static void cmdq_handle_error_done(struct cmdq *cmdq,
> >> +   struct cmdq_thread *thread, u32 irq_flag)
> >> +{
> >> +struct cmdq_task *task, *tmp, *curr_task = NULL;
> >> +u32 curr_pa;
> >> +struct cmdq_cb_data cmdq_cb_data;
> >> +bool err;
> >> +
> >> +if (irq_flag & CMDQ_THR_IRQ_ERROR)
> >> +err = true;
> >> +else if (irq_flag & CMDQ_THR_IRQ_DONE)
> >> +err = false;
> >> +else
> >> +return;
> >> +
> >> +curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
> >> +
> >> +list_for_each_entry_safe(task, tmp, >task_busy_list,
> >> + list_entry) {
> >> +if (curr_pa >= task->pa_base &&
> >> +curr_pa < (task->pa_base + task->command_size))
> >
> > What are you checking here? It seems as if you make some implcit
> > assumptions about pa_base and the order of execution of
> > commands in the
> > thread. Is it save to do so? Does dma_alloc_coherent give any
> > guarantees
> > about dma_handle?
> 
>  1. Check what is the current running task in this GCE thread.
>  2. Yes.
>  3. Yes, CMDQ doesn't use iommu, so physical address is continuous.
> 
> >>>
> >>> Yes, physical addresses might be continous, but AFAIK there is no
> >>> guarantee that the dma_handle address is steadily growing, when
> >>> calling
> >>> dma_alloc_coherent. And if I understand the code correctly, you
> >>> use this
> >>> assumption to decide if the task picked from task_busy_list is
> >>> currently
> >>> executing. So I think this mecanism is not working.
> >>
> >> I don't use dma_handle address, and just use physical addresses.
> >>From CPU's point of view, tasks are linked by the busy list.
> >>From GCE's point of view, tasks are linked by the JUMP command.
> >>
> >>> In which cases does the HW thread raise an interrupt.
> >>> In case of error. When does CMDQ_THR_IRQ_DONE get raised?
> >>
> >> GCE will raise interrupt if any task is done or error.
> >> However, GCE is fast, so CPU may get multiple done tasks
> >> when it is running ISR.
> >>
> >> In case of error, that GCE thread will pause and raise interrupt.
> >> So, CPU may get multiple done tasks and one error task.
> >>
> >
> > I think we should reimplement the ISR mechanism. Can't we just read
> > CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
> > cmdq_handle_error_done to the thread_fn? You will need to pass
> > information from the handler to thread_fn, but that shouldn't be an
> > issue. AFAIK interrupts are disabled in the handler, so we should stay
> > there as short as possible. Traversing task_busy_list is expensive, so
> > we need to do it in a thread context.
> 
>  Actually, our initial implementation is similar to your suggestion,
>  but display needs CMDQ to return callback function very precisely,
>  else display will drop frame.
>  For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
>  and CMDQ needs to call callback function in ISR.
>  If we defer callback to workqueue, the time interval may be larger than
>  32 ms.sometimes.
> 
> >>>
> >>> I think the problem is, that you implemented the workqueue as a ordered
> >>> workqueue, so there is no parallel processing. I'm still not sure why
> >>> you need the workqueue to be ordered. Can you please explain.
> >>
> >> The order should be kept.
> >> Let me use mouse cursor as an example.
> >> If task 1 means move mouse cursor to point A, task 2 means point B,
> >> and task 3 means point C, our expected result is A -> B -> C.
> >> If the order is not kept, the result could become A -> C -> B.
> >>
> >
> > Got it, thanks for the clarification.
> >
> 
> I think a way to get rid of the workqueue is to use a timer, which gets 
> programmed to the time a timeout in the first task in the busy list 
> would happen. Everytime we update the busy list (e.g. because of task 
> got finished by the thread), we update the timer. When the 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-07 Thread Horng-Shyang Liao
Hi Matthias,

On Tue, 2016-06-07 at 19:04 +0200, Matthias Brugger wrote:
> 
> On 30/05/16 05:19, HS Liao wrote:
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help read/write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> >
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> 
> [...]
> 
> > +static void cmdq_handle_error_done(struct cmdq *cmdq,
> > +  struct cmdq_thread *thread, u32 irq_flag)
> > +{
> > +   struct cmdq_task *task, *tmp, *curr_task = NULL;
> > +   u32 curr_pa;
> > +   struct cmdq_cb_data cmdq_cb_data;
> > +   bool err;
> > +
> > +   if (irq_flag & CMDQ_THR_IRQ_ERROR)
> > +   err = true;
> > +   else if (irq_flag & CMDQ_THR_IRQ_DONE)
> > +   err = false;
> > +   else
> > +   return;
> > +
> > +   curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
> > +
> > +   list_for_each_entry_safe(task, tmp, >task_busy_list,
> > +list_entry) {
> > +   if (curr_pa >= task->pa_base &&
> > +   curr_pa < (task->pa_base + task->command_size))
> > +   curr_task = task;
> > +   if (task->cb.cb) {
> > +   cmdq_cb_data.err = curr_task ? err : false;
> > +   cmdq_cb_data.data = task->cb.data;
> > +   task->cb.cb(cmdq_cb_data);
> > +   }
> 
> I think this is not right. If we got an IRQ_DONE, then the current task 
> is in execution, we should not call the callback until it has finished.

Thanks for your finding. This is a bug from CMDQ v6.
I will fix it in next version (CMDQ v9).

> 
> Regards,
> Matthias

Thanks,
HS



Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-07 Thread Horng-Shyang Liao
Hi Matthias,

On Tue, 2016-06-07 at 19:04 +0200, Matthias Brugger wrote:
> 
> On 30/05/16 05:19, HS Liao wrote:
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help read/write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> >
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> 
> [...]
> 
> > +static void cmdq_handle_error_done(struct cmdq *cmdq,
> > +  struct cmdq_thread *thread, u32 irq_flag)
> > +{
> > +   struct cmdq_task *task, *tmp, *curr_task = NULL;
> > +   u32 curr_pa;
> > +   struct cmdq_cb_data cmdq_cb_data;
> > +   bool err;
> > +
> > +   if (irq_flag & CMDQ_THR_IRQ_ERROR)
> > +   err = true;
> > +   else if (irq_flag & CMDQ_THR_IRQ_DONE)
> > +   err = false;
> > +   else
> > +   return;
> > +
> > +   curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
> > +
> > +   list_for_each_entry_safe(task, tmp, >task_busy_list,
> > +list_entry) {
> > +   if (curr_pa >= task->pa_base &&
> > +   curr_pa < (task->pa_base + task->command_size))
> > +   curr_task = task;
> > +   if (task->cb.cb) {
> > +   cmdq_cb_data.err = curr_task ? err : false;
> > +   cmdq_cb_data.data = task->cb.data;
> > +   task->cb.cb(cmdq_cb_data);
> > +   }
> 
> I think this is not right. If we got an IRQ_DONE, then the current task 
> is in execution, we should not call the callback until it has finished.

Thanks for your finding. This is a bug from CMDQ v6.
I will fix it in next version (CMDQ v9).

> 
> Regards,
> Matthias

Thanks,
HS



Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-07 Thread Matthias Brugger



On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---


[...]


+static void cmdq_handle_error_done(struct cmdq *cmdq,
+  struct cmdq_thread *thread, u32 irq_flag)
+{
+   struct cmdq_task *task, *tmp, *curr_task = NULL;
+   u32 curr_pa;
+   struct cmdq_cb_data cmdq_cb_data;
+   bool err;
+
+   if (irq_flag & CMDQ_THR_IRQ_ERROR)
+   err = true;
+   else if (irq_flag & CMDQ_THR_IRQ_DONE)
+   err = false;
+   else
+   return;
+
+   curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+   list_for_each_entry_safe(task, tmp, >task_busy_list,
+list_entry) {
+   if (curr_pa >= task->pa_base &&
+   curr_pa < (task->pa_base + task->command_size))
+   curr_task = task;
+   if (task->cb.cb) {
+   cmdq_cb_data.err = curr_task ? err : false;
+   cmdq_cb_data.data = task->cb.data;
+   task->cb.cb(cmdq_cb_data);
+   }


I think this is not right. If we got an IRQ_DONE, then the current task 
is in execution, we should not call the callback until it has finished.


Regards,
Matthias


Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-07 Thread Matthias Brugger



On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---


[...]


+static void cmdq_handle_error_done(struct cmdq *cmdq,
+  struct cmdq_thread *thread, u32 irq_flag)
+{
+   struct cmdq_task *task, *tmp, *curr_task = NULL;
+   u32 curr_pa;
+   struct cmdq_cb_data cmdq_cb_data;
+   bool err;
+
+   if (irq_flag & CMDQ_THR_IRQ_ERROR)
+   err = true;
+   else if (irq_flag & CMDQ_THR_IRQ_DONE)
+   err = false;
+   else
+   return;
+
+   curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+   list_for_each_entry_safe(task, tmp, >task_busy_list,
+list_entry) {
+   if (curr_pa >= task->pa_base &&
+   curr_pa < (task->pa_base + task->command_size))
+   curr_task = task;
+   if (task->cb.cb) {
+   cmdq_cb_data.err = curr_task ? err : false;
+   cmdq_cb_data.data = task->cb.data;
+   task->cb.cb(cmdq_cb_data);
+   }


I think this is not right. If we got an IRQ_DONE, then the current task 
is in execution, we should not call the callback until it has finished.


Regards,
Matthias


Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-07 Thread Matthias Brugger



On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
   From CPU's point of view, tasks are linked by the busy list.
   From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets 
programmed to the time a timeout in the first task in the busy list 
would happen. Everytime we update the busy list (e.g. because of task 
got finished by the thread), we update the timer. When the timer 
triggers, which hopefully won't happen too often, we return timeout on 
the busy list elements, until the time is lower then the actual time.


At least with this we can reduce the data structures in this driver and 
make it more lightweight.


Best regards,
Matthias


I keep thinking about how to get rid of the two data structures,
task_busy_list and the task_release_wq. We need the latter for the
only
sake of getting a timeout.

Did you have a look on how the mailbox framework handles this?
By the way, what is the reason to not implement the whole driver as a
mailbox controller? For me, this driver looks like a good fit.


CMDQ needs to encode commands for GCE hardware. We think this behavior
should be put in CMDQ driver, and client just call CMDQ functions.
Therefore, if we want to use mailbox framework, cmdq_rec must be
mailbox client, and the others must be mailbox controller.



You mean the functions to fill the cmdq_rec and execute it?
I think this should be part of the driver.


Yes.


Jassi, can you have a look on the interface this 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-07 Thread Matthias Brugger



On 03/06/16 15:11, Matthias Brugger wrote:




[...]


+
+smp_mb(); /* modify jump before enable thread */
+}
+
+cmdq_thread_writel(thread, task->pa_base +
task->command_size,
+   CMDQ_THR_END_ADDR);
+cmdq_thread_resume(thread);
+}
+list_move_tail(>list_entry, >task_busy_list);
+spin_unlock_irqrestore(>exec_lock, flags);
+}
+
+static void cmdq_handle_error_done(struct cmdq *cmdq,
+   struct cmdq_thread *thread, u32 irq_flag)
+{
+struct cmdq_task *task, *tmp, *curr_task = NULL;
+u32 curr_pa;
+struct cmdq_cb_data cmdq_cb_data;
+bool err;
+
+if (irq_flag & CMDQ_THR_IRQ_ERROR)
+err = true;
+else if (irq_flag & CMDQ_THR_IRQ_DONE)
+err = false;
+else
+return;
+
+curr_pa = cmdq_thread_readl(thread, CMDQ_THR_CURR_ADDR);
+
+list_for_each_entry_safe(task, tmp, >task_busy_list,
+ list_entry) {
+if (curr_pa >= task->pa_base &&
+curr_pa < (task->pa_base + task->command_size))


What are you checking here? It seems as if you make some implcit
assumptions about pa_base and the order of execution of
commands in the
thread. Is it save to do so? Does dma_alloc_coherent give any
guarantees
about dma_handle?


1. Check what is the current running task in this GCE thread.
2. Yes.
3. Yes, CMDQ doesn't use iommu, so physical address is continuous.



Yes, physical addresses might be continous, but AFAIK there is no
guarantee that the dma_handle address is steadily growing, when
calling
dma_alloc_coherent. And if I understand the code correctly, you
use this
assumption to decide if the task picked from task_busy_list is
currently
executing. So I think this mecanism is not working.


I don't use dma_handle address, and just use physical addresses.
   From CPU's point of view, tasks are linked by the busy list.
   From GCE's point of view, tasks are linked by the JUMP command.


In which cases does the HW thread raise an interrupt.
In case of error. When does CMDQ_THR_IRQ_DONE get raised?


GCE will raise interrupt if any task is done or error.
However, GCE is fast, so CPU may get multiple done tasks
when it is running ISR.

In case of error, that GCE thread will pause and raise interrupt.
So, CPU may get multiple done tasks and one error task.



I think we should reimplement the ISR mechanism. Can't we just read
CURR_IRQ_STATUS and THR_IRQ_STATUS in the handler and leave
cmdq_handle_error_done to the thread_fn? You will need to pass
information from the handler to thread_fn, but that shouldn't be an
issue. AFAIK interrupts are disabled in the handler, so we should stay
there as short as possible. Traversing task_busy_list is expensive, so
we need to do it in a thread context.


Actually, our initial implementation is similar to your suggestion,
but display needs CMDQ to return callback function very precisely,
else display will drop frame.
For display, CMDQ interrupt will be raised every 16 ~ 17 ms,
and CMDQ needs to call callback function in ISR.
If we defer callback to workqueue, the time interval may be larger than
32 ms.sometimes.



I think the problem is, that you implemented the workqueue as a ordered
workqueue, so there is no parallel processing. I'm still not sure why
you need the workqueue to be ordered. Can you please explain.


The order should be kept.
Let me use mouse cursor as an example.
If task 1 means move mouse cursor to point A, task 2 means point B,
and task 3 means point C, our expected result is A -> B -> C.
If the order is not kept, the result could become A -> C -> B.



Got it, thanks for the clarification.



I think a way to get rid of the workqueue is to use a timer, which gets 
programmed to the time a timeout in the first task in the busy list 
would happen. Everytime we update the busy list (e.g. because of task 
got finished by the thread), we update the timer. When the timer 
triggers, which hopefully won't happen too often, we return timeout on 
the busy list elements, until the time is lower then the actual time.


At least with this we can reduce the data structures in this driver and 
make it more lightweight.


Best regards,
Matthias


I keep thinking about how to get rid of the two data structures,
task_busy_list and the task_release_wq. We need the latter for the
only
sake of getting a timeout.

Did you have a look on how the mailbox framework handles this?
By the way, what is the reason to not implement the whole driver as a
mailbox controller? For me, this driver looks like a good fit.


CMDQ needs to encode commands for GCE hardware. We think this behavior
should be put in CMDQ driver, and client just call CMDQ functions.
Therefore, if we want to use mailbox framework, cmdq_rec must be
mailbox client, and the others must be mailbox controller.



You mean the functions to fill the cmdq_rec and execute it?
I think this should be part of the driver.


Yes.


Jassi, can you have a look on the interface this 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-06 Thread Horng-Shyang Liao
On Fri, 2016-06-03 at 18:41 +0530, Jassi Brar wrote:
> On Fri, Jun 3, 2016 at 4:48 PM, Matthias Brugger  
> wrote:
> > On 03/06/16 08:12, Horng-Shyang Liao wrote:
> >> On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:
> 
> >>> I keep thinking about how to get rid of the two data structures,
> >>> task_busy_list and the task_release_wq. We need the latter for the only
> >>> sake of getting a timeout.
> >>>
> >>> Did you have a look on how the mailbox framework handles this?
> >>> By the way, what is the reason to not implement the whole driver as a
> >>> mailbox controller? For me, this driver looks like a good fit.
> >>
> >>
> >> CMDQ needs to encode commands for GCE hardware. We think this behavior
> >> should be put in CMDQ driver, and client just call CMDQ functions.
> >> Therefore, if we want to use mailbox framework, cmdq_rec must be
> >> mailbox client, and the others must be mailbox controller.
> >>
> >
> > You mean the functions to fill the cmdq_rec and execute it?
> > I think this should be part of the driver.
> >
> > Jassi, can you have a look on the interface this driver exports [0].
> > They are needed to actually create the message which will be send.
> > Could something like this be part of a mailbox driver?
> >
> > [0] https://patchwork.kernel.org/patch/9140221/
> >
> Packet creating/parsing should not be a part of controller driver. As
> the log of this patch says, today it is used for only display but in
> future it could work with other h/w as well, so it makes sense to have
> mailbox api do the message queuing, the controller driver do the
> send/receive and client drivers implement display and other h/w
> specific packaging of data (protocol handling).
> 
> So yes, I think this could use mailbox api.
> 
> Cheers.

I will try to rewrite CMDQ driver by mailbox framework and discuss with
you if I encounter other problems.

Thanks,
HS



Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-06 Thread Horng-Shyang Liao
On Fri, 2016-06-03 at 18:41 +0530, Jassi Brar wrote:
> On Fri, Jun 3, 2016 at 4:48 PM, Matthias Brugger  
> wrote:
> > On 03/06/16 08:12, Horng-Shyang Liao wrote:
> >> On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:
> 
> >>> I keep thinking about how to get rid of the two data structures,
> >>> task_busy_list and the task_release_wq. We need the latter for the only
> >>> sake of getting a timeout.
> >>>
> >>> Did you have a look on how the mailbox framework handles this?
> >>> By the way, what is the reason to not implement the whole driver as a
> >>> mailbox controller? For me, this driver looks like a good fit.
> >>
> >>
> >> CMDQ needs to encode commands for GCE hardware. We think this behavior
> >> should be put in CMDQ driver, and client just call CMDQ functions.
> >> Therefore, if we want to use mailbox framework, cmdq_rec must be
> >> mailbox client, and the others must be mailbox controller.
> >>
> >
> > You mean the functions to fill the cmdq_rec and execute it?
> > I think this should be part of the driver.
> >
> > Jassi, can you have a look on the interface this driver exports [0].
> > They are needed to actually create the message which will be send.
> > Could something like this be part of a mailbox driver?
> >
> > [0] https://patchwork.kernel.org/patch/9140221/
> >
> Packet creating/parsing should not be a part of controller driver. As
> the log of this patch says, today it is used for only display but in
> future it could work with other h/w as well, so it makes sense to have
> mailbox api do the message queuing, the controller driver do the
> send/receive and client drivers implement display and other h/w
> specific packaging of data (protocol handling).
> 
> So yes, I think this could use mailbox api.
> 
> Cheers.

I will try to rewrite CMDQ driver by mailbox framework and discuss with
you if I encounter other problems.

Thanks,
HS



Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-06 Thread Horng-Shyang Liao
Hi Matthias, Jassi,

On Fri, 2016-06-03 at 18:41 +0530, Jassi Brar wrote:
> On Fri, Jun 3, 2016 at 4:48 PM, Matthias Brugger  
> wrote:
> > On 03/06/16 08:12, Horng-Shyang Liao wrote:
> >> On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:
> 
> >>> I keep thinking about how to get rid of the two data structures,
> >>> task_busy_list and the task_release_wq. We need the latter for the only
> >>> sake of getting a timeout.
> >>>
> >>> Did you have a look on how the mailbox framework handles this?
> >>> By the way, what is the reason to not implement the whole driver as a
> >>> mailbox controller? For me, this driver looks like a good fit.
> >>
> >>
> >> CMDQ needs to encode commands for GCE hardware. We think this behavior
> >> should be put in CMDQ driver, and client just call CMDQ functions.
> >> Therefore, if we want to use mailbox framework, cmdq_rec must be
> >> mailbox client, and the others must be mailbox controller.
> >>
> >
> > You mean the functions to fill the cmdq_rec and execute it?
> > I think this should be part of the driver.
> >
> > Jassi, can you have a look on the interface this driver exports [0].
> > They are needed to actually create the message which will be send.
> > Could something like this be part of a mailbox driver?
> >
> > [0] https://patchwork.kernel.org/patch/9140221/
> >
> Packet creating/parsing should not be a part of controller driver. As
> the log of this patch says, today it is used for only display but in
> future it could work with other h/w as well, so it makes sense to have
> mailbox api do the message queuing, the controller driver do the
> send/receive and client drivers implement display and other h/w
> specific packaging of data (protocol handling).
> 
> So yes, I think this could use mailbox api.
> 
> Cheers.


Let me use display as an example to do some further explanation
about CMDQ in advance. You can think CMDQ is a shadow register
replacement. Therefore, we use cmdq_rec_write(_mask), cmdq_rec_wfe, and
cmdq_rec_clear_event instead of accessing registers, and use
cmdq_rec_flush(_async) instead of atomic swap.

If we use mailbox to do the message queue, we can use mailbox framework
to implement flush and callback. However, I don't think mailbox is
suitable for cmdq_rec_write(_mask), cmdq_rec_wfe, and
cmdq_rec_clear_event since they are just record some commands. Is this
the same as your comment "Packet creating/parsing should not be a part
of controller driver."?

Therefore, do you mean we use mailbox framework to implement flush and
callback and keep other interfaces? Just want to confirm that I get the
correct idea from you. Many thanks for your kindly reply.

Thanks,
HS




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-06 Thread Horng-Shyang Liao
Hi Matthias, Jassi,

On Fri, 2016-06-03 at 18:41 +0530, Jassi Brar wrote:
> On Fri, Jun 3, 2016 at 4:48 PM, Matthias Brugger  
> wrote:
> > On 03/06/16 08:12, Horng-Shyang Liao wrote:
> >> On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:
> 
> >>> I keep thinking about how to get rid of the two data structures,
> >>> task_busy_list and the task_release_wq. We need the latter for the only
> >>> sake of getting a timeout.
> >>>
> >>> Did you have a look on how the mailbox framework handles this?
> >>> By the way, what is the reason to not implement the whole driver as a
> >>> mailbox controller? For me, this driver looks like a good fit.
> >>
> >>
> >> CMDQ needs to encode commands for GCE hardware. We think this behavior
> >> should be put in CMDQ driver, and client just call CMDQ functions.
> >> Therefore, if we want to use mailbox framework, cmdq_rec must be
> >> mailbox client, and the others must be mailbox controller.
> >>
> >
> > You mean the functions to fill the cmdq_rec and execute it?
> > I think this should be part of the driver.
> >
> > Jassi, can you have a look on the interface this driver exports [0].
> > They are needed to actually create the message which will be send.
> > Could something like this be part of a mailbox driver?
> >
> > [0] https://patchwork.kernel.org/patch/9140221/
> >
> Packet creating/parsing should not be a part of controller driver. As
> the log of this patch says, today it is used for only display but in
> future it could work with other h/w as well, so it makes sense to have
> mailbox api do the message queuing, the controller driver do the
> send/receive and client drivers implement display and other h/w
> specific packaging of data (protocol handling).
> 
> So yes, I think this could use mailbox api.
> 
> Cheers.


Let me use display as an example to do some further explanation
about CMDQ in advance. You can think CMDQ is a shadow register
replacement. Therefore, we use cmdq_rec_write(_mask), cmdq_rec_wfe, and
cmdq_rec_clear_event instead of accessing registers, and use
cmdq_rec_flush(_async) instead of atomic swap.

If we use mailbox to do the message queue, we can use mailbox framework
to implement flush and callback. However, I don't think mailbox is
suitable for cmdq_rec_write(_mask), cmdq_rec_wfe, and
cmdq_rec_clear_event since they are just record some commands. Is this
the same as your comment "Packet creating/parsing should not be a part
of controller driver."?

Therefore, do you mean we use mailbox framework to implement flush and
callback and keep other interfaces? Just want to confirm that I get the
correct idea from you. Many thanks for your kindly reply.

Thanks,
HS




Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-03 Thread Jassi Brar
On Fri, Jun 3, 2016 at 4:48 PM, Matthias Brugger  wrote:
> On 03/06/16 08:12, Horng-Shyang Liao wrote:
>> On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:

>>> I keep thinking about how to get rid of the two data structures,
>>> task_busy_list and the task_release_wq. We need the latter for the only
>>> sake of getting a timeout.
>>>
>>> Did you have a look on how the mailbox framework handles this?
>>> By the way, what is the reason to not implement the whole driver as a
>>> mailbox controller? For me, this driver looks like a good fit.
>>
>>
>> CMDQ needs to encode commands for GCE hardware. We think this behavior
>> should be put in CMDQ driver, and client just call CMDQ functions.
>> Therefore, if we want to use mailbox framework, cmdq_rec must be
>> mailbox client, and the others must be mailbox controller.
>>
>
> You mean the functions to fill the cmdq_rec and execute it?
> I think this should be part of the driver.
>
> Jassi, can you have a look on the interface this driver exports [0].
> They are needed to actually create the message which will be send.
> Could something like this be part of a mailbox driver?
>
> [0] https://patchwork.kernel.org/patch/9140221/
>
Packet creating/parsing should not be a part of controller driver. As
the log of this patch says, today it is used for only display but in
future it could work with other h/w as well, so it makes sense to have
mailbox api do the message queuing, the controller driver do the
send/receive and client drivers implement display and other h/w
specific packaging of data (protocol handling).

So yes, I think this could use mailbox api.

Cheers.


Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-03 Thread Jassi Brar
On Fri, Jun 3, 2016 at 4:48 PM, Matthias Brugger  wrote:
> On 03/06/16 08:12, Horng-Shyang Liao wrote:
>> On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:

>>> I keep thinking about how to get rid of the two data structures,
>>> task_busy_list and the task_release_wq. We need the latter for the only
>>> sake of getting a timeout.
>>>
>>> Did you have a look on how the mailbox framework handles this?
>>> By the way, what is the reason to not implement the whole driver as a
>>> mailbox controller? For me, this driver looks like a good fit.
>>
>>
>> CMDQ needs to encode commands for GCE hardware. We think this behavior
>> should be put in CMDQ driver, and client just call CMDQ functions.
>> Therefore, if we want to use mailbox framework, cmdq_rec must be
>> mailbox client, and the others must be mailbox controller.
>>
>
> You mean the functions to fill the cmdq_rec and execute it?
> I think this should be part of the driver.
>
> Jassi, can you have a look on the interface this driver exports [0].
> They are needed to actually create the message which will be send.
> Could something like this be part of a mailbox driver?
>
> [0] https://patchwork.kernel.org/patch/9140221/
>
Packet creating/parsing should not be a part of controller driver. As
the log of this patch says, today it is used for only display but in
future it could work with other h/w as well, so it makes sense to have
mailbox api do the message queuing, the controller driver do the
send/receive and client drivers implement display and other h/w
specific packaging of data (protocol handling).

So yes, I think this could use mailbox api.

Cheers.


Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-03 Thread Matthias Brugger



On 03/06/16 14:13, Horng-Shyang Liao wrote:

Hi Matthias,

On Fri, 2016-06-03 at 13:18 +0200, Matthias Brugger wrote:


On 03/06/16 08:12, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:


On 01/06/16 11:57, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:


On 31/05/16 10:36, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:


On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
  drivers/soc/mediatek/Kconfig|  10 +
  drivers/soc/mediatek/Makefile   |   1 +
  drivers/soc/mediatek/mtk-cmdq.c | 943 

  include/soc/mediatek/cmdq.h | 197 +
  4 files changed, 1151 insertions(+)
  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
  create mode 100644 include/soc/mediatek/cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..c4ad75c 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
  #
  # MediaTek SoC drivers
  #
+config MTK_CMDQ
+   bool "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST


depends on ARM64 ?


Will add ARM64.


+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
  config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..f7397ef 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
new file mode 100644
index 000..e9d6e1c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
+#define CMDQ_CLK_NAME  "gce"


We can put the names in directly to un-bloat the defines.


I will use the names directly and remove defines.


+
+#define CMDQ_CURR_IRQ_STATUS   0x010
+#define CMDQ_CURR_LOADED_THR   0x018
+#define CMDQ_THR_SLOT_CYCLES   0x030
+
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SHIFT 0x080


Wouldn't be CMDQ_THR_SIZE more accurate?


Will rename it.


+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_CFG   0x40
+
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-03 Thread Matthias Brugger



On 03/06/16 14:13, Horng-Shyang Liao wrote:

Hi Matthias,

On Fri, 2016-06-03 at 13:18 +0200, Matthias Brugger wrote:


On 03/06/16 08:12, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:


On 01/06/16 11:57, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:


On 31/05/16 10:36, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:


On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
  drivers/soc/mediatek/Kconfig|  10 +
  drivers/soc/mediatek/Makefile   |   1 +
  drivers/soc/mediatek/mtk-cmdq.c | 943 

  include/soc/mediatek/cmdq.h | 197 +
  4 files changed, 1151 insertions(+)
  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
  create mode 100644 include/soc/mediatek/cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..c4ad75c 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
  #
  # MediaTek SoC drivers
  #
+config MTK_CMDQ
+   bool "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST


depends on ARM64 ?


Will add ARM64.


+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
  config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..f7397ef 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
new file mode 100644
index 000..e9d6e1c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
+#define CMDQ_CLK_NAME  "gce"


We can put the names in directly to un-bloat the defines.


I will use the names directly and remove defines.


+
+#define CMDQ_CURR_IRQ_STATUS   0x010
+#define CMDQ_CURR_LOADED_THR   0x018
+#define CMDQ_THR_SLOT_CYCLES   0x030
+
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SHIFT 0x080


Wouldn't be CMDQ_THR_SIZE more accurate?


Will rename it.


+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_CFG   0x40
+
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-03 Thread Horng-Shyang Liao
Hi Matthias,

On Fri, 2016-06-03 at 13:18 +0200, Matthias Brugger wrote:
> 
> On 03/06/16 08:12, Horng-Shyang Liao wrote:
> > Hi Mathias,
> >
> > Please see my inline reply.
> >
> > On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:
> >>
> >> On 01/06/16 11:57, Horng-Shyang Liao wrote:
> >>> Hi Mathias,
> >>>
> >>> Please see my inline reply.
> >>>
> >>> On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:
> 
>  On 31/05/16 10:36, Horng-Shyang Liao wrote:
> > Hi Mathias,
> >
> > Please see my inline reply.
> >
> > On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:
> >>
> >> On 30/05/16 05:19, HS Liao wrote:
> >>> This patch is first version of Mediatek Command Queue(CMDQ) driver. 
> >>> The
> >>> CMDQ is used to help read/write registers with critical time 
> >>> limitation,
> >>> such as updating display configuration during the vblank. It controls
> >>> Global Command Engine (GCE) hardware to achieve this requirement.
> >>> Currently, CMDQ only supports display related hardwares, but we expect
> >>> it can be extended to other hardwares for future requirements.
> >>>
> >>> Signed-off-by: HS Liao 
> >>> Signed-off-by: CK Hu 
> >>> ---
> >>>  drivers/soc/mediatek/Kconfig|  10 +
> >>>  drivers/soc/mediatek/Makefile   |   1 +
> >>>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> >>> 
> >>>  include/soc/mediatek/cmdq.h | 197 +
> >>>  4 files changed, 1151 insertions(+)
> >>>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> >>>  create mode 100644 include/soc/mediatek/cmdq.h
> >>>
> >>> diff --git a/drivers/soc/mediatek/Kconfig 
> >>> b/drivers/soc/mediatek/Kconfig
> >>> index 0a4ea80..c4ad75c 100644
> >>> --- a/drivers/soc/mediatek/Kconfig
> >>> +++ b/drivers/soc/mediatek/Kconfig
> >>> @@ -1,6 +1,16 @@
> >>>  #
> >>>  # MediaTek SoC drivers
> >>>  #
> >>> +config MTK_CMDQ
> >>> + bool "MediaTek CMDQ Support"
> >>> + depends on ARCH_MEDIATEK || COMPILE_TEST
> 
>  depends on ARM64 ?
> >>>
> >>> Will add ARM64.
> >>>
> >>> + select MTK_INFRACFG
> >>> + help
> >>> +   Say yes here to add support for the MediaTek Command Queue 
> >>> (CMDQ)
> >>> +   driver. The CMDQ is used to help read/write registers with 
> >>> critical
> >>> +   time limitation, such as updating display configuration 
> >>> during the
> >>> +   vblank.
> >>> +
> >>>  config MTK_INFRACFG
> >>>   bool "MediaTek INFRACFG Support"
> >>>   depends on ARCH_MEDIATEK || COMPILE_TEST
> >>> diff --git a/drivers/soc/mediatek/Makefile 
> >>> b/drivers/soc/mediatek/Makefile
> >>> index 12998b0..f7397ef 100644
> >>> --- a/drivers/soc/mediatek/Makefile
> >>> +++ b/drivers/soc/mediatek/Makefile
> >>> @@ -1,3 +1,4 @@
> >>> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
> >>>  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >>>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >>>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> >>> diff --git a/drivers/soc/mediatek/mtk-cmdq.c 
> >>> b/drivers/soc/mediatek/mtk-cmdq.c
> >>> new file mode 100644
> >>> index 000..e9d6e1c
> >>> --- /dev/null
> >>> +++ b/drivers/soc/mediatek/mtk-cmdq.c
> >>> @@ -0,0 +1,943 @@
> >>> +/*
> >>> + * Copyright (c) 2015 MediaTek Inc.
> >>> + *
> >>> + * This program is free software; you can redistribute it and/or 
> >>> modify
> >>> + * it under the terms of the GNU General Public License version 2 as
> >>> + * published by the Free Software Foundation.
> >>> + *
> >>> + * This program is distributed in the hope that it will be useful,
> >>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >>> + * GNU General Public License for more details.
> >>> + */
> >>> +
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +
> >>> +#define CMDQ_INITIAL_CMD_BLOCK_SIZE  PAGE_SIZE
> >>> +#define CMDQ_INST_SIZE   8 /* instruction is 
> >>> 64-bit */
> >>> +#define CMDQ_TIMEOUT_MS  1000
> >>> +#define CMDQ_IRQ_MASK0x
> >>> +#define CMDQ_DRIVER_DEVICE_NAME  "mtk_cmdq"
> >>> +#define CMDQ_CLK_NAME 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-03 Thread Horng-Shyang Liao
Hi Matthias,

On Fri, 2016-06-03 at 13:18 +0200, Matthias Brugger wrote:
> 
> On 03/06/16 08:12, Horng-Shyang Liao wrote:
> > Hi Mathias,
> >
> > Please see my inline reply.
> >
> > On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:
> >>
> >> On 01/06/16 11:57, Horng-Shyang Liao wrote:
> >>> Hi Mathias,
> >>>
> >>> Please see my inline reply.
> >>>
> >>> On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:
> 
>  On 31/05/16 10:36, Horng-Shyang Liao wrote:
> > Hi Mathias,
> >
> > Please see my inline reply.
> >
> > On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:
> >>
> >> On 30/05/16 05:19, HS Liao wrote:
> >>> This patch is first version of Mediatek Command Queue(CMDQ) driver. 
> >>> The
> >>> CMDQ is used to help read/write registers with critical time 
> >>> limitation,
> >>> such as updating display configuration during the vblank. It controls
> >>> Global Command Engine (GCE) hardware to achieve this requirement.
> >>> Currently, CMDQ only supports display related hardwares, but we expect
> >>> it can be extended to other hardwares for future requirements.
> >>>
> >>> Signed-off-by: HS Liao 
> >>> Signed-off-by: CK Hu 
> >>> ---
> >>>  drivers/soc/mediatek/Kconfig|  10 +
> >>>  drivers/soc/mediatek/Makefile   |   1 +
> >>>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> >>> 
> >>>  include/soc/mediatek/cmdq.h | 197 +
> >>>  4 files changed, 1151 insertions(+)
> >>>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> >>>  create mode 100644 include/soc/mediatek/cmdq.h
> >>>
> >>> diff --git a/drivers/soc/mediatek/Kconfig 
> >>> b/drivers/soc/mediatek/Kconfig
> >>> index 0a4ea80..c4ad75c 100644
> >>> --- a/drivers/soc/mediatek/Kconfig
> >>> +++ b/drivers/soc/mediatek/Kconfig
> >>> @@ -1,6 +1,16 @@
> >>>  #
> >>>  # MediaTek SoC drivers
> >>>  #
> >>> +config MTK_CMDQ
> >>> + bool "MediaTek CMDQ Support"
> >>> + depends on ARCH_MEDIATEK || COMPILE_TEST
> 
>  depends on ARM64 ?
> >>>
> >>> Will add ARM64.
> >>>
> >>> + select MTK_INFRACFG
> >>> + help
> >>> +   Say yes here to add support for the MediaTek Command Queue 
> >>> (CMDQ)
> >>> +   driver. The CMDQ is used to help read/write registers with 
> >>> critical
> >>> +   time limitation, such as updating display configuration 
> >>> during the
> >>> +   vblank.
> >>> +
> >>>  config MTK_INFRACFG
> >>>   bool "MediaTek INFRACFG Support"
> >>>   depends on ARCH_MEDIATEK || COMPILE_TEST
> >>> diff --git a/drivers/soc/mediatek/Makefile 
> >>> b/drivers/soc/mediatek/Makefile
> >>> index 12998b0..f7397ef 100644
> >>> --- a/drivers/soc/mediatek/Makefile
> >>> +++ b/drivers/soc/mediatek/Makefile
> >>> @@ -1,3 +1,4 @@
> >>> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
> >>>  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >>>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >>>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> >>> diff --git a/drivers/soc/mediatek/mtk-cmdq.c 
> >>> b/drivers/soc/mediatek/mtk-cmdq.c
> >>> new file mode 100644
> >>> index 000..e9d6e1c
> >>> --- /dev/null
> >>> +++ b/drivers/soc/mediatek/mtk-cmdq.c
> >>> @@ -0,0 +1,943 @@
> >>> +/*
> >>> + * Copyright (c) 2015 MediaTek Inc.
> >>> + *
> >>> + * This program is free software; you can redistribute it and/or 
> >>> modify
> >>> + * it under the terms of the GNU General Public License version 2 as
> >>> + * published by the Free Software Foundation.
> >>> + *
> >>> + * This program is distributed in the hope that it will be useful,
> >>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >>> + * GNU General Public License for more details.
> >>> + */
> >>> +
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +
> >>> +#define CMDQ_INITIAL_CMD_BLOCK_SIZE  PAGE_SIZE
> >>> +#define CMDQ_INST_SIZE   8 /* instruction is 
> >>> 64-bit */
> >>> +#define CMDQ_TIMEOUT_MS  1000
> >>> +#define CMDQ_IRQ_MASK0x
> >>> +#define CMDQ_DRIVER_DEVICE_NAME  "mtk_cmdq"
> >>> +#define CMDQ_CLK_NAME"gce"
> >>
> >> We can put 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-03 Thread Matthias Brugger



On 03/06/16 08:12, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:


On 01/06/16 11:57, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:


On 31/05/16 10:36, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:


On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
 drivers/soc/mediatek/Kconfig|  10 +
 drivers/soc/mediatek/Makefile   |   1 +
 drivers/soc/mediatek/mtk-cmdq.c | 943 

 include/soc/mediatek/cmdq.h | 197 +
 4 files changed, 1151 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
 create mode 100644 include/soc/mediatek/cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..c4ad75c 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
 #
 # MediaTek SoC drivers
 #
+config MTK_CMDQ
+   bool "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST


depends on ARM64 ?


Will add ARM64.


+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..f7397ef 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
new file mode 100644
index 000..e9d6e1c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
+#define CMDQ_CLK_NAME  "gce"


We can put the names in directly to un-bloat the defines.


I will use the names directly and remove defines.


+
+#define CMDQ_CURR_IRQ_STATUS   0x010
+#define CMDQ_CURR_LOADED_THR   0x018
+#define CMDQ_THR_SLOT_CYCLES   0x030
+
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SHIFT 0x080


Wouldn't be CMDQ_THR_SIZE more accurate?


Will rename it.


+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_CFG   0x40
+
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_PRIORITY  3
+#define CMDQ_THR_IRQ_DONE  0x1
+#define 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-03 Thread Matthias Brugger



On 03/06/16 08:12, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:


On 01/06/16 11:57, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:


On 31/05/16 10:36, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:


On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
 drivers/soc/mediatek/Kconfig|  10 +
 drivers/soc/mediatek/Makefile   |   1 +
 drivers/soc/mediatek/mtk-cmdq.c | 943 

 include/soc/mediatek/cmdq.h | 197 +
 4 files changed, 1151 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
 create mode 100644 include/soc/mediatek/cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..c4ad75c 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
 #
 # MediaTek SoC drivers
 #
+config MTK_CMDQ
+   bool "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST


depends on ARM64 ?


Will add ARM64.


+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
 config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..f7397ef 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
 obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
 obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
 obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
new file mode 100644
index 000..e9d6e1c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
+#define CMDQ_CLK_NAME  "gce"


We can put the names in directly to un-bloat the defines.


I will use the names directly and remove defines.


+
+#define CMDQ_CURR_IRQ_STATUS   0x010
+#define CMDQ_CURR_LOADED_THR   0x018
+#define CMDQ_THR_SLOT_CYCLES   0x030
+
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SHIFT 0x080


Wouldn't be CMDQ_THR_SIZE more accurate?


Will rename it.


+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_CFG   0x40
+
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_PRIORITY  3
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-03 Thread Horng-Shyang Liao
Hi Mathias,

Please see my inline reply.

On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:
> 
> On 01/06/16 11:57, Horng-Shyang Liao wrote:
> > Hi Mathias,
> >
> > Please see my inline reply.
> >
> > On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:
> >>
> >> On 31/05/16 10:36, Horng-Shyang Liao wrote:
> >>> Hi Mathias,
> >>>
> >>> Please see my inline reply.
> >>>
> >>> On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:
> 
>  On 30/05/16 05:19, HS Liao wrote:
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help read/write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> >
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> > drivers/soc/mediatek/Kconfig|  10 +
> > drivers/soc/mediatek/Makefile   |   1 +
> > drivers/soc/mediatek/mtk-cmdq.c | 943 
> > 
> > include/soc/mediatek/cmdq.h | 197 +
> > 4 files changed, 1151 insertions(+)
> > create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> > create mode 100644 include/soc/mediatek/cmdq.h
> >
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index 0a4ea80..c4ad75c 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -1,6 +1,16 @@
> > #
> > # MediaTek SoC drivers
> > #
> > +config MTK_CMDQ
> > +   bool "MediaTek CMDQ Support"
> > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> >>
> >> depends on ARM64 ?
> >
> > Will add ARM64.
> >
> > +   select MTK_INFRACFG
> > +   help
> > + Say yes here to add support for the MediaTek Command Queue 
> > (CMDQ)
> > + driver. The CMDQ is used to help read/write registers with 
> > critical
> > + time limitation, such as updating display configuration 
> > during the
> > + vblank.
> > +
> > config MTK_INFRACFG
> > bool "MediaTek INFRACFG Support"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> > diff --git a/drivers/soc/mediatek/Makefile 
> > b/drivers/soc/mediatek/Makefile
> > index 12998b0..f7397ef 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,4 @@
> > +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
> > obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> > obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> > obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-cmdq.c 
> > b/drivers/soc/mediatek/mtk-cmdq.c
> > new file mode 100644
> > index 000..e9d6e1c
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-cmdq.c
> > @@ -0,0 +1,943 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
> > +#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
> > +#define CMDQ_TIMEOUT_MS1000
> > +#define CMDQ_IRQ_MASK  0x
> > +#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
> > +#define CMDQ_CLK_NAME  "gce"
> 
>  We can put the names in directly to un-bloat the defines.
> >>>
> >>> I will use the names directly and remove defines.
> >>>
> > +
> > +#define CMDQ_CURR_IRQ_STATUS   0x010
> > +#define CMDQ_CURR_LOADED_THR   0x018
> > +#define CMDQ_THR_SLOT_CYCLES   0x030
> > +
> > +#define CMDQ_THR_BASE  0x100
> > +#define CMDQ_THR_SHIFT 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-03 Thread Horng-Shyang Liao
Hi Mathias,

Please see my inline reply.

On Thu, 2016-06-02 at 10:46 +0200, Matthias Brugger wrote:
> 
> On 01/06/16 11:57, Horng-Shyang Liao wrote:
> > Hi Mathias,
> >
> > Please see my inline reply.
> >
> > On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:
> >>
> >> On 31/05/16 10:36, Horng-Shyang Liao wrote:
> >>> Hi Mathias,
> >>>
> >>> Please see my inline reply.
> >>>
> >>> On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:
> 
>  On 30/05/16 05:19, HS Liao wrote:
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help read/write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> >
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> > drivers/soc/mediatek/Kconfig|  10 +
> > drivers/soc/mediatek/Makefile   |   1 +
> > drivers/soc/mediatek/mtk-cmdq.c | 943 
> > 
> > include/soc/mediatek/cmdq.h | 197 +
> > 4 files changed, 1151 insertions(+)
> > create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> > create mode 100644 include/soc/mediatek/cmdq.h
> >
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index 0a4ea80..c4ad75c 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -1,6 +1,16 @@
> > #
> > # MediaTek SoC drivers
> > #
> > +config MTK_CMDQ
> > +   bool "MediaTek CMDQ Support"
> > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> >>
> >> depends on ARM64 ?
> >
> > Will add ARM64.
> >
> > +   select MTK_INFRACFG
> > +   help
> > + Say yes here to add support for the MediaTek Command Queue 
> > (CMDQ)
> > + driver. The CMDQ is used to help read/write registers with 
> > critical
> > + time limitation, such as updating display configuration 
> > during the
> > + vblank.
> > +
> > config MTK_INFRACFG
> > bool "MediaTek INFRACFG Support"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> > diff --git a/drivers/soc/mediatek/Makefile 
> > b/drivers/soc/mediatek/Makefile
> > index 12998b0..f7397ef 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,4 @@
> > +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
> > obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> > obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> > obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-cmdq.c 
> > b/drivers/soc/mediatek/mtk-cmdq.c
> > new file mode 100644
> > index 000..e9d6e1c
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-cmdq.c
> > @@ -0,0 +1,943 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
> > +#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
> > +#define CMDQ_TIMEOUT_MS1000
> > +#define CMDQ_IRQ_MASK  0x
> > +#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
> > +#define CMDQ_CLK_NAME  "gce"
> 
>  We can put the names in directly to un-bloat the defines.
> >>>
> >>> I will use the names directly and remove defines.
> >>>
> > +
> > +#define CMDQ_CURR_IRQ_STATUS   0x010
> > +#define CMDQ_CURR_LOADED_THR   0x018
> > +#define CMDQ_THR_SLOT_CYCLES   0x030
> > +
> > +#define CMDQ_THR_BASE  0x100
> > +#define CMDQ_THR_SHIFT 0x080
> 
>  Wouldn't be CMDQ_THR_SIZE 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-02 Thread Matthias Brugger



On 01/06/16 11:57, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:


On 31/05/16 10:36, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:


On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
drivers/soc/mediatek/Kconfig|  10 +
drivers/soc/mediatek/Makefile   |   1 +
drivers/soc/mediatek/mtk-cmdq.c | 943 

include/soc/mediatek/cmdq.h | 197 +
4 files changed, 1151 insertions(+)
create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
create mode 100644 include/soc/mediatek/cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..c4ad75c 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
#
# MediaTek SoC drivers
#
+config MTK_CMDQ
+   bool "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST


depends on ARM64 ?


Will add ARM64.


+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..f7397ef 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
new file mode 100644
index 000..e9d6e1c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
+#define CMDQ_CLK_NAME  "gce"


We can put the names in directly to un-bloat the defines.


I will use the names directly and remove defines.


+
+#define CMDQ_CURR_IRQ_STATUS   0x010
+#define CMDQ_CURR_LOADED_THR   0x018
+#define CMDQ_THR_SLOT_CYCLES   0x030
+
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SHIFT 0x080


Wouldn't be CMDQ_THR_SIZE more accurate?


Will rename it.


+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_CFG   0x40
+
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_PRIORITY  3
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN0x13 /* done + error */


#define CMDQ_THR_IRQ_EN (CMDQ_THR_IRQ_ERROR | 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-02 Thread Matthias Brugger



On 01/06/16 11:57, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:


On 31/05/16 10:36, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:


On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
drivers/soc/mediatek/Kconfig|  10 +
drivers/soc/mediatek/Makefile   |   1 +
drivers/soc/mediatek/mtk-cmdq.c | 943 

include/soc/mediatek/cmdq.h | 197 +
4 files changed, 1151 insertions(+)
create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
create mode 100644 include/soc/mediatek/cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..c4ad75c 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
#
# MediaTek SoC drivers
#
+config MTK_CMDQ
+   bool "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST


depends on ARM64 ?


Will add ARM64.


+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..f7397ef 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
new file mode 100644
index 000..e9d6e1c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
+#define CMDQ_CLK_NAME  "gce"


We can put the names in directly to un-bloat the defines.


I will use the names directly and remove defines.


+
+#define CMDQ_CURR_IRQ_STATUS   0x010
+#define CMDQ_CURR_LOADED_THR   0x018
+#define CMDQ_THR_SLOT_CYCLES   0x030
+
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SHIFT 0x080


Wouldn't be CMDQ_THR_SIZE more accurate?


Will rename it.


+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_CFG   0x40
+
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_PRIORITY  3
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN0x13 /* done + error */


#define CMDQ_THR_IRQ_EN (CMDQ_THR_IRQ_ERROR | CMDQ_THR_IRQ_DONE)


Will do.


+#define 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-01 Thread Horng-Shyang Liao
Hi Mathias,

Please see my inline reply.

On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:
> 
> On 31/05/16 10:36, Horng-Shyang Liao wrote:
> > Hi Mathias,
> >
> > Please see my inline reply.
> >
> > On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:
> >>
> >> On 30/05/16 05:19, HS Liao wrote:
> >>> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> >>> CMDQ is used to help read/write registers with critical time limitation,
> >>> such as updating display configuration during the vblank. It controls
> >>> Global Command Engine (GCE) hardware to achieve this requirement.
> >>> Currently, CMDQ only supports display related hardwares, but we expect
> >>> it can be extended to other hardwares for future requirements.
> >>>
> >>> Signed-off-by: HS Liao 
> >>> Signed-off-by: CK Hu 
> >>> ---
> >>>drivers/soc/mediatek/Kconfig|  10 +
> >>>drivers/soc/mediatek/Makefile   |   1 +
> >>>drivers/soc/mediatek/mtk-cmdq.c | 943 
> >>> 
> >>>include/soc/mediatek/cmdq.h | 197 +
> >>>4 files changed, 1151 insertions(+)
> >>>create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> >>>create mode 100644 include/soc/mediatek/cmdq.h
> >>>
> >>> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> >>> index 0a4ea80..c4ad75c 100644
> >>> --- a/drivers/soc/mediatek/Kconfig
> >>> +++ b/drivers/soc/mediatek/Kconfig
> >>> @@ -1,6 +1,16 @@
> >>>#
> >>># MediaTek SoC drivers
> >>>#
> >>> +config MTK_CMDQ
> >>> + bool "MediaTek CMDQ Support"
> >>> + depends on ARCH_MEDIATEK || COMPILE_TEST
> 
> depends on ARM64 ?

Will add ARM64.

> >>> + select MTK_INFRACFG
> >>> + help
> >>> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> >>> +   driver. The CMDQ is used to help read/write registers with critical
> >>> +   time limitation, such as updating display configuration during the
> >>> +   vblank.
> >>> +
> >>>config MTK_INFRACFG
> >>>   bool "MediaTek INFRACFG Support"
> >>>   depends on ARCH_MEDIATEK || COMPILE_TEST
> >>> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> >>> index 12998b0..f7397ef 100644
> >>> --- a/drivers/soc/mediatek/Makefile
> >>> +++ b/drivers/soc/mediatek/Makefile
> >>> @@ -1,3 +1,4 @@
> >>> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
> >>>obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >>>obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >>>obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> >>> diff --git a/drivers/soc/mediatek/mtk-cmdq.c 
> >>> b/drivers/soc/mediatek/mtk-cmdq.c
> >>> new file mode 100644
> >>> index 000..e9d6e1c
> >>> --- /dev/null
> >>> +++ b/drivers/soc/mediatek/mtk-cmdq.c
> >>> @@ -0,0 +1,943 @@
> >>> +/*
> >>> + * Copyright (c) 2015 MediaTek Inc.
> >>> + *
> >>> + * This program is free software; you can redistribute it and/or modify
> >>> + * it under the terms of the GNU General Public License version 2 as
> >>> + * published by the Free Software Foundation.
> >>> + *
> >>> + * This program is distributed in the hope that it will be useful,
> >>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >>> + * GNU General Public License for more details.
> >>> + */
> >>> +
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +
> >>> +#define CMDQ_INITIAL_CMD_BLOCK_SIZE  PAGE_SIZE
> >>> +#define CMDQ_INST_SIZE   8 /* instruction is 64-bit */
> >>> +#define CMDQ_TIMEOUT_MS  1000
> >>> +#define CMDQ_IRQ_MASK0x
> >>> +#define CMDQ_DRIVER_DEVICE_NAME  "mtk_cmdq"
> >>> +#define CMDQ_CLK_NAME"gce"
> >>
> >> We can put the names in directly to un-bloat the defines.
> >
> > I will use the names directly and remove defines.
> >
> >>> +
> >>> +#define CMDQ_CURR_IRQ_STATUS 0x010
> >>> +#define CMDQ_CURR_LOADED_THR 0x018
> >>> +#define CMDQ_THR_SLOT_CYCLES 0x030
> >>> +
> >>> +#define CMDQ_THR_BASE0x100
> >>> +#define CMDQ_THR_SHIFT   0x080
> >>
> >> Wouldn't be CMDQ_THR_SIZE more accurate?
> >
> > Will rename it.
> >
> >>> +#define CMDQ_THR_WARM_RESET  0x00
> >>> +#define CMDQ_THR_ENABLE_TASK 0x04
> >>> +#define CMDQ_THR_SUSPEND_TASK0x08
> >>> +#define CMDQ_THR_CURR_STATUS 0x0c
> >>> +#define CMDQ_THR_IRQ_STATUS  0x10
> >>> +#define CMDQ_THR_IRQ_ENABLE  0x14
> >>> +#define CMDQ_THR_CURR_ADDR   0x20
> >>> +#define CMDQ_THR_END_ADDR0x24

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-06-01 Thread Horng-Shyang Liao
Hi Mathias,

Please see my inline reply.

On Tue, 2016-05-31 at 22:04 +0200, Matthias Brugger wrote:
> 
> On 31/05/16 10:36, Horng-Shyang Liao wrote:
> > Hi Mathias,
> >
> > Please see my inline reply.
> >
> > On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:
> >>
> >> On 30/05/16 05:19, HS Liao wrote:
> >>> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> >>> CMDQ is used to help read/write registers with critical time limitation,
> >>> such as updating display configuration during the vblank. It controls
> >>> Global Command Engine (GCE) hardware to achieve this requirement.
> >>> Currently, CMDQ only supports display related hardwares, but we expect
> >>> it can be extended to other hardwares for future requirements.
> >>>
> >>> Signed-off-by: HS Liao 
> >>> Signed-off-by: CK Hu 
> >>> ---
> >>>drivers/soc/mediatek/Kconfig|  10 +
> >>>drivers/soc/mediatek/Makefile   |   1 +
> >>>drivers/soc/mediatek/mtk-cmdq.c | 943 
> >>> 
> >>>include/soc/mediatek/cmdq.h | 197 +
> >>>4 files changed, 1151 insertions(+)
> >>>create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> >>>create mode 100644 include/soc/mediatek/cmdq.h
> >>>
> >>> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> >>> index 0a4ea80..c4ad75c 100644
> >>> --- a/drivers/soc/mediatek/Kconfig
> >>> +++ b/drivers/soc/mediatek/Kconfig
> >>> @@ -1,6 +1,16 @@
> >>>#
> >>># MediaTek SoC drivers
> >>>#
> >>> +config MTK_CMDQ
> >>> + bool "MediaTek CMDQ Support"
> >>> + depends on ARCH_MEDIATEK || COMPILE_TEST
> 
> depends on ARM64 ?

Will add ARM64.

> >>> + select MTK_INFRACFG
> >>> + help
> >>> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> >>> +   driver. The CMDQ is used to help read/write registers with critical
> >>> +   time limitation, such as updating display configuration during the
> >>> +   vblank.
> >>> +
> >>>config MTK_INFRACFG
> >>>   bool "MediaTek INFRACFG Support"
> >>>   depends on ARCH_MEDIATEK || COMPILE_TEST
> >>> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> >>> index 12998b0..f7397ef 100644
> >>> --- a/drivers/soc/mediatek/Makefile
> >>> +++ b/drivers/soc/mediatek/Makefile
> >>> @@ -1,3 +1,4 @@
> >>> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
> >>>obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >>>obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >>>obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> >>> diff --git a/drivers/soc/mediatek/mtk-cmdq.c 
> >>> b/drivers/soc/mediatek/mtk-cmdq.c
> >>> new file mode 100644
> >>> index 000..e9d6e1c
> >>> --- /dev/null
> >>> +++ b/drivers/soc/mediatek/mtk-cmdq.c
> >>> @@ -0,0 +1,943 @@
> >>> +/*
> >>> + * Copyright (c) 2015 MediaTek Inc.
> >>> + *
> >>> + * This program is free software; you can redistribute it and/or modify
> >>> + * it under the terms of the GNU General Public License version 2 as
> >>> + * published by the Free Software Foundation.
> >>> + *
> >>> + * This program is distributed in the hope that it will be useful,
> >>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> >>> + * GNU General Public License for more details.
> >>> + */
> >>> +
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +#include 
> >>> +
> >>> +#define CMDQ_INITIAL_CMD_BLOCK_SIZE  PAGE_SIZE
> >>> +#define CMDQ_INST_SIZE   8 /* instruction is 64-bit */
> >>> +#define CMDQ_TIMEOUT_MS  1000
> >>> +#define CMDQ_IRQ_MASK0x
> >>> +#define CMDQ_DRIVER_DEVICE_NAME  "mtk_cmdq"
> >>> +#define CMDQ_CLK_NAME"gce"
> >>
> >> We can put the names in directly to un-bloat the defines.
> >
> > I will use the names directly and remove defines.
> >
> >>> +
> >>> +#define CMDQ_CURR_IRQ_STATUS 0x010
> >>> +#define CMDQ_CURR_LOADED_THR 0x018
> >>> +#define CMDQ_THR_SLOT_CYCLES 0x030
> >>> +
> >>> +#define CMDQ_THR_BASE0x100
> >>> +#define CMDQ_THR_SHIFT   0x080
> >>
> >> Wouldn't be CMDQ_THR_SIZE more accurate?
> >
> > Will rename it.
> >
> >>> +#define CMDQ_THR_WARM_RESET  0x00
> >>> +#define CMDQ_THR_ENABLE_TASK 0x04
> >>> +#define CMDQ_THR_SUSPEND_TASK0x08
> >>> +#define CMDQ_THR_CURR_STATUS 0x0c
> >>> +#define CMDQ_THR_IRQ_STATUS  0x10
> >>> +#define CMDQ_THR_IRQ_ENABLE  0x14
> >>> +#define CMDQ_THR_CURR_ADDR   0x20
> >>> +#define CMDQ_THR_END_ADDR0x24
> >>> +#define CMDQ_THR_CFG   

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-31 Thread Matthias Brugger



On 31/05/16 10:36, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:


On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
   drivers/soc/mediatek/Kconfig|  10 +
   drivers/soc/mediatek/Makefile   |   1 +
   drivers/soc/mediatek/mtk-cmdq.c | 943 

   include/soc/mediatek/cmdq.h | 197 +
   4 files changed, 1151 insertions(+)
   create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
   create mode 100644 include/soc/mediatek/cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..c4ad75c 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
   #
   # MediaTek SoC drivers
   #
+config MTK_CMDQ
+   bool "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST


depends on ARM64 ?


+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
   config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..f7397ef 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
   obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
   obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
   obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
new file mode 100644
index 000..e9d6e1c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
+#define CMDQ_CLK_NAME  "gce"


We can put the names in directly to un-bloat the defines.


I will use the names directly and remove defines.


+
+#define CMDQ_CURR_IRQ_STATUS   0x010
+#define CMDQ_CURR_LOADED_THR   0x018
+#define CMDQ_THR_SLOT_CYCLES   0x030
+
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SHIFT 0x080


Wouldn't be CMDQ_THR_SIZE more accurate?


Will rename it.


+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_CFG   0x40
+
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_PRIORITY  3
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN0x13 /* done + error */


#define CMDQ_THR_IRQ_EN (CMDQ_THR_IRQ_ERROR | CMDQ_THR_IRQ_DONE)


Will do.


+#define CMDQ_THR_IRQ_MASK  0x13


never used.


Will remove.


+#define CMDQ_THR_EXECUTING BIT(31)
+
+#define CMDQ_ARG_A_WRITE_MASK

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-31 Thread Matthias Brugger



On 31/05/16 10:36, Horng-Shyang Liao wrote:

Hi Mathias,

Please see my inline reply.

On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:


On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
   drivers/soc/mediatek/Kconfig|  10 +
   drivers/soc/mediatek/Makefile   |   1 +
   drivers/soc/mediatek/mtk-cmdq.c | 943 

   include/soc/mediatek/cmdq.h | 197 +
   4 files changed, 1151 insertions(+)
   create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
   create mode 100644 include/soc/mediatek/cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..c4ad75c 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
   #
   # MediaTek SoC drivers
   #
+config MTK_CMDQ
+   bool "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST


depends on ARM64 ?


+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
   config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..f7397ef 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
   obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
   obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
   obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
new file mode 100644
index 000..e9d6e1c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
+#define CMDQ_CLK_NAME  "gce"


We can put the names in directly to un-bloat the defines.


I will use the names directly and remove defines.


+
+#define CMDQ_CURR_IRQ_STATUS   0x010
+#define CMDQ_CURR_LOADED_THR   0x018
+#define CMDQ_THR_SLOT_CYCLES   0x030
+
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SHIFT 0x080


Wouldn't be CMDQ_THR_SIZE more accurate?


Will rename it.


+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_CFG   0x40
+
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_PRIORITY  3
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN0x13 /* done + error */


#define CMDQ_THR_IRQ_EN (CMDQ_THR_IRQ_ERROR | CMDQ_THR_IRQ_DONE)


Will do.


+#define CMDQ_THR_IRQ_MASK  0x13


never used.


Will remove.


+#define CMDQ_THR_EXECUTING BIT(31)
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_SUBSYS_MASK

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-31 Thread Horng-Shyang Liao
Hi Mathias,

Please see my inline reply.

On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:
> 
> On 30/05/16 05:19, HS Liao wrote:
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help read/write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> >
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> >   drivers/soc/mediatek/Kconfig|  10 +
> >   drivers/soc/mediatek/Makefile   |   1 +
> >   drivers/soc/mediatek/mtk-cmdq.c | 943 
> > 
> >   include/soc/mediatek/cmdq.h | 197 +
> >   4 files changed, 1151 insertions(+)
> >   create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> >   create mode 100644 include/soc/mediatek/cmdq.h
> >
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index 0a4ea80..c4ad75c 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -1,6 +1,16 @@
> >   #
> >   # MediaTek SoC drivers
> >   #
> > +config MTK_CMDQ
> > +   bool "MediaTek CMDQ Support"
> > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> > +   select MTK_INFRACFG
> > +   help
> > + Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > + driver. The CMDQ is used to help read/write registers with critical
> > + time limitation, such as updating display configuration during the
> > + vblank.
> > +
> >   config MTK_INFRACFG
> > bool "MediaTek INFRACFG Support"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..f7397ef 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,4 @@
> > +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
> >   obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >   obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >   obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-cmdq.c 
> > b/drivers/soc/mediatek/mtk-cmdq.c
> > new file mode 100644
> > index 000..e9d6e1c
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-cmdq.c
> > @@ -0,0 +1,943 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
> > +#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
> > +#define CMDQ_TIMEOUT_MS1000
> > +#define CMDQ_IRQ_MASK  0x
> > +#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
> > +#define CMDQ_CLK_NAME  "gce"
> 
> We can put the names in directly to un-bloat the defines.

I will use the names directly and remove defines.

> > +
> > +#define CMDQ_CURR_IRQ_STATUS   0x010
> > +#define CMDQ_CURR_LOADED_THR   0x018
> > +#define CMDQ_THR_SLOT_CYCLES   0x030
> > +
> > +#define CMDQ_THR_BASE  0x100
> > +#define CMDQ_THR_SHIFT 0x080
> 
> Wouldn't be CMDQ_THR_SIZE more accurate?

Will rename it.

> > +#define CMDQ_THR_WARM_RESET0x00
> > +#define CMDQ_THR_ENABLE_TASK   0x04
> > +#define CMDQ_THR_SUSPEND_TASK  0x08
> > +#define CMDQ_THR_CURR_STATUS   0x0c
> > +#define CMDQ_THR_IRQ_STATUS0x10
> > +#define CMDQ_THR_IRQ_ENABLE0x14
> > +#define CMDQ_THR_CURR_ADDR 0x20
> > +#define CMDQ_THR_END_ADDR  0x24
> > +#define CMDQ_THR_CFG   0x40
> > +
> > +#define CMDQ_THR_ENABLED   0x1
> > +#define CMDQ_THR_DISABLED  0x0
> > +#define CMDQ_THR_SUSPEND   0x1
> > +#define CMDQ_THR_RESUME0x0
> > +#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
> > +#define CMDQ_THR_DO_WARM_RESET BIT(0)
> > +#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
> > +#define CMDQ_THR_PRIORITY  3
> > 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-31 Thread Horng-Shyang Liao
Hi Mathias,

Please see my inline reply.

On Mon, 2016-05-30 at 17:31 +0200, Matthias Brugger wrote:
> 
> On 30/05/16 05:19, HS Liao wrote:
> > This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> > CMDQ is used to help read/write registers with critical time limitation,
> > such as updating display configuration during the vblank. It controls
> > Global Command Engine (GCE) hardware to achieve this requirement.
> > Currently, CMDQ only supports display related hardwares, but we expect
> > it can be extended to other hardwares for future requirements.
> >
> > Signed-off-by: HS Liao 
> > Signed-off-by: CK Hu 
> > ---
> >   drivers/soc/mediatek/Kconfig|  10 +
> >   drivers/soc/mediatek/Makefile   |   1 +
> >   drivers/soc/mediatek/mtk-cmdq.c | 943 
> > 
> >   include/soc/mediatek/cmdq.h | 197 +
> >   4 files changed, 1151 insertions(+)
> >   create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
> >   create mode 100644 include/soc/mediatek/cmdq.h
> >
> > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> > index 0a4ea80..c4ad75c 100644
> > --- a/drivers/soc/mediatek/Kconfig
> > +++ b/drivers/soc/mediatek/Kconfig
> > @@ -1,6 +1,16 @@
> >   #
> >   # MediaTek SoC drivers
> >   #
> > +config MTK_CMDQ
> > +   bool "MediaTek CMDQ Support"
> > +   depends on ARCH_MEDIATEK || COMPILE_TEST
> > +   select MTK_INFRACFG
> > +   help
> > + Say yes here to add support for the MediaTek Command Queue (CMDQ)
> > + driver. The CMDQ is used to help read/write registers with critical
> > + time limitation, such as updating display configuration during the
> > + vblank.
> > +
> >   config MTK_INFRACFG
> > bool "MediaTek INFRACFG Support"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> > index 12998b0..f7397ef 100644
> > --- a/drivers/soc/mediatek/Makefile
> > +++ b/drivers/soc/mediatek/Makefile
> > @@ -1,3 +1,4 @@
> > +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
> >   obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
> >   obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
> >   obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> > diff --git a/drivers/soc/mediatek/mtk-cmdq.c 
> > b/drivers/soc/mediatek/mtk-cmdq.c
> > new file mode 100644
> > index 000..e9d6e1c
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mtk-cmdq.c
> > @@ -0,0 +1,943 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
> > +#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
> > +#define CMDQ_TIMEOUT_MS1000
> > +#define CMDQ_IRQ_MASK  0x
> > +#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
> > +#define CMDQ_CLK_NAME  "gce"
> 
> We can put the names in directly to un-bloat the defines.

I will use the names directly and remove defines.

> > +
> > +#define CMDQ_CURR_IRQ_STATUS   0x010
> > +#define CMDQ_CURR_LOADED_THR   0x018
> > +#define CMDQ_THR_SLOT_CYCLES   0x030
> > +
> > +#define CMDQ_THR_BASE  0x100
> > +#define CMDQ_THR_SHIFT 0x080
> 
> Wouldn't be CMDQ_THR_SIZE more accurate?

Will rename it.

> > +#define CMDQ_THR_WARM_RESET0x00
> > +#define CMDQ_THR_ENABLE_TASK   0x04
> > +#define CMDQ_THR_SUSPEND_TASK  0x08
> > +#define CMDQ_THR_CURR_STATUS   0x0c
> > +#define CMDQ_THR_IRQ_STATUS0x10
> > +#define CMDQ_THR_IRQ_ENABLE0x14
> > +#define CMDQ_THR_CURR_ADDR 0x20
> > +#define CMDQ_THR_END_ADDR  0x24
> > +#define CMDQ_THR_CFG   0x40
> > +
> > +#define CMDQ_THR_ENABLED   0x1
> > +#define CMDQ_THR_DISABLED  0x0
> > +#define CMDQ_THR_SUSPEND   0x1
> > +#define CMDQ_THR_RESUME0x0
> > +#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
> > +#define CMDQ_THR_DO_WARM_RESET BIT(0)
> > +#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
> > +#define CMDQ_THR_PRIORITY  3
> > +#define CMDQ_THR_IRQ_DONE  0x1
> > 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-30 Thread Matthias Brugger



On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
  drivers/soc/mediatek/Kconfig|  10 +
  drivers/soc/mediatek/Makefile   |   1 +
  drivers/soc/mediatek/mtk-cmdq.c | 943 
  include/soc/mediatek/cmdq.h | 197 +
  4 files changed, 1151 insertions(+)
  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
  create mode 100644 include/soc/mediatek/cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..c4ad75c 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
  #
  # MediaTek SoC drivers
  #
+config MTK_CMDQ
+   bool "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
  config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..f7397ef 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
new file mode 100644
index 000..e9d6e1c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
+#define CMDQ_CLK_NAME  "gce"


We can put the names in directly to un-bloat the defines.


+
+#define CMDQ_CURR_IRQ_STATUS   0x010
+#define CMDQ_CURR_LOADED_THR   0x018
+#define CMDQ_THR_SLOT_CYCLES   0x030
+
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SHIFT 0x080


Wouldn't be CMDQ_THR_SIZE more accurate?


+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_CFG   0x40
+
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_PRIORITY  3
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN0x13 /* done + error */


#define CMDQ_THR_IRQ_EN (CMDQ_THR_IRQ_ERROR | CMDQ_THR_IRQ_DONE)


+#define CMDQ_THR_IRQ_MASK  0x13


never used.


+#define CMDQ_THR_EXECUTING BIT(31)
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_SUBSYS_MASK   0x1f
+#define CMDQ_OP_CODE_MASK  0xff00
+
+#define CMDQ_OP_CODE_SHIFT 24


Couldn't we connect the mask with the shift, or aren't they related?

#define CMDQ_OP_CODE_MASK (0xff << CMDQ_OP_CODE_SHIFT)


Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-30 Thread Matthias Brugger



On 30/05/16 05:19, HS Liao wrote:

This patch is first version of Mediatek Command Queue(CMDQ) driver. The
CMDQ is used to help read/write registers with critical time limitation,
such as updating display configuration during the vblank. It controls
Global Command Engine (GCE) hardware to achieve this requirement.
Currently, CMDQ only supports display related hardwares, but we expect
it can be extended to other hardwares for future requirements.

Signed-off-by: HS Liao 
Signed-off-by: CK Hu 
---
  drivers/soc/mediatek/Kconfig|  10 +
  drivers/soc/mediatek/Makefile   |   1 +
  drivers/soc/mediatek/mtk-cmdq.c | 943 
  include/soc/mediatek/cmdq.h | 197 +
  4 files changed, 1151 insertions(+)
  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
  create mode 100644 include/soc/mediatek/cmdq.h

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 0a4ea80..c4ad75c 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
  #
  # MediaTek SoC drivers
  #
+config MTK_CMDQ
+   bool "MediaTek CMDQ Support"
+   depends on ARCH_MEDIATEK || COMPILE_TEST
+   select MTK_INFRACFG
+   help
+ Say yes here to add support for the MediaTek Command Queue (CMDQ)
+ driver. The CMDQ is used to help read/write registers with critical
+ time limitation, such as updating display configuration during the
+ vblank.
+
  config MTK_INFRACFG
bool "MediaTek INFRACFG Support"
depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 12998b0..f7397ef 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
new file mode 100644
index 000..e9d6e1c
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-cmdq.c
@@ -0,0 +1,943 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CMDQ_INITIAL_CMD_BLOCK_SIZEPAGE_SIZE
+#define CMDQ_INST_SIZE 8 /* instruction is 64-bit */
+#define CMDQ_TIMEOUT_MS1000
+#define CMDQ_IRQ_MASK  0x
+#define CMDQ_DRIVER_DEVICE_NAME"mtk_cmdq"
+#define CMDQ_CLK_NAME  "gce"


We can put the names in directly to un-bloat the defines.


+
+#define CMDQ_CURR_IRQ_STATUS   0x010
+#define CMDQ_CURR_LOADED_THR   0x018
+#define CMDQ_THR_SLOT_CYCLES   0x030
+
+#define CMDQ_THR_BASE  0x100
+#define CMDQ_THR_SHIFT 0x080


Wouldn't be CMDQ_THR_SIZE more accurate?


+#define CMDQ_THR_WARM_RESET0x00
+#define CMDQ_THR_ENABLE_TASK   0x04
+#define CMDQ_THR_SUSPEND_TASK  0x08
+#define CMDQ_THR_CURR_STATUS   0x0c
+#define CMDQ_THR_IRQ_STATUS0x10
+#define CMDQ_THR_IRQ_ENABLE0x14
+#define CMDQ_THR_CURR_ADDR 0x20
+#define CMDQ_THR_END_ADDR  0x24
+#define CMDQ_THR_CFG   0x40
+
+#define CMDQ_THR_ENABLED   0x1
+#define CMDQ_THR_DISABLED  0x0
+#define CMDQ_THR_SUSPEND   0x1
+#define CMDQ_THR_RESUME0x0
+#define CMDQ_THR_STATUS_SUSPENDED  BIT(1)
+#define CMDQ_THR_DO_WARM_RESET BIT(0)
+#define CMDQ_THR_ACTIVE_SLOT_CYCLES0x3200
+#define CMDQ_THR_PRIORITY  3
+#define CMDQ_THR_IRQ_DONE  0x1
+#define CMDQ_THR_IRQ_ERROR 0x12
+#define CMDQ_THR_IRQ_EN0x13 /* done + error */


#define CMDQ_THR_IRQ_EN (CMDQ_THR_IRQ_ERROR | CMDQ_THR_IRQ_DONE)


+#define CMDQ_THR_IRQ_MASK  0x13


never used.


+#define CMDQ_THR_EXECUTING BIT(31)
+
+#define CMDQ_ARG_A_WRITE_MASK  0x
+#define CMDQ_SUBSYS_MASK   0x1f
+#define CMDQ_OP_CODE_MASK  0xff00
+
+#define CMDQ_OP_CODE_SHIFT 24


Couldn't we connect the mask with the shift, or aren't they related?

#define CMDQ_OP_CODE_MASK (0xff << CMDQ_OP_CODE_SHIFT)


+#define CMDQ_SUBSYS_SHIFT  

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-30 Thread Horng-Shyang Liao
Hi CK,

Reply inline.

On Mon, 2016-05-30 at 14:49 +0800, CK Hu wrote:
> Hi, HS:
> 
> Some comments inline.
> 
> On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
...
> > +static void cmdq_thread_irq_handler(struct cmdq *cmdq, int tid)
> > +{
> > +   struct cmdq_thread *thread = >thread[tid];
> > +   unsigned long flags = 0L;
> > +   u32 irq_flag;
> > +
> > +   spin_lock_irqsave(>exec_lock, flags);
> > +
> > +   irq_flag = cmdq_thread_readl(thread, CMDQ_THR_IRQ_STATUS);
> > +   cmdq_thread_writel(thread, ~irq_flag, CMDQ_THR_IRQ_STATUS);
> > +
> > +   /*
> > +* Another CPU core could run "release task" right before we acquire
> > +* the spin lock, and thus reset / disable this GCE thread, so we
> > +* need to check the enable bit of this GCE thread.
> > +*/
> > +   if (!(cmdq_thread_readl(thread, CMDQ_THR_ENABLE_TASK) &
> > + CMDQ_THR_ENABLED))
> > +   irq_flag = 0;
> 
> These three statement (clear irq flag and detect thread enable) can be
> moved into cmdq_handle_error_done() and the duplicated part in
> cmdq_task_handle_error_result() can be removed. Even though
> cmdq_task_handle_error_result() need not check thread enable, it would
> not influence the flow.

Will do.

> > +
> > +   cmdq_handle_error_done(cmdq, thread, irq_flag);
> > +   spin_unlock_irqrestore(>exec_lock, flags);
> > +}
...
> > +static int cmdq_task_handle_error_result(struct cmdq_task *task)
> > +{
> > +   struct cmdq *cmdq = task->cmdq;
> > +   struct device *dev = cmdq->dev;
> > +   struct cmdq_thread *thread = task->thread;
> > +   struct cmdq_task *next_task, *prev_task;
> > +   u32 irq_flag;
> > +
> > +   /* suspend GCE thread to ensure consistency */
> > +   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
> > +
> > +   /* ISR has handled this error task */
> > +   if (task->task_state == TASK_STATE_ERROR) {
> > +   next_task = list_first_entry_or_null(>task_busy_list,
> > +   struct cmdq_task, list_entry);
> > +   if (next_task) /* move to next task */
> > +   cmdq_thread_writel(thread, next_task->pa_base,
> > +  CMDQ_THR_CURR_ADDR);
> > +   cmdq_thread_resume(thread);
> > +   return -ECANCELED;
> > +   }
> > +
> > +   /*
> > +* Save next_task and prev_task in advance
> > +* since cmdq_handle_error_done will remove list_entry.
> > +*/
> > +   next_task = prev_task = NULL;
> > +   if (task->list_entry.next != >task_busy_list)
> > +   next_task = list_next_entry(task, list_entry);
> > +   if (task->list_entry.prev != >task_busy_list)
> > +   prev_task = list_prev_entry(task, list_entry);
> 
> I think there is always no previous task because task order in
> thread->task_busy_list is the same as in cmdq->task_release_wq. So each
> task processed by release work should be the first item in
> thread->task_busy_list or be removed from thread->task_busy_list.

Will remove previous task.

> > +
> > +   /*
> > +* Although IRQ is disabled, GCE continues to execute.
> > +* It may have pending IRQ before GCE thread is suspended,
> > +* so check this condition again.
> > +*/
> > +   irq_flag = cmdq_thread_readl(thread, CMDQ_THR_IRQ_STATUS);
> > +   cmdq_handle_error_done(cmdq, thread, irq_flag);
> > +   cmdq_thread_writel(thread, ~irq_flag, CMDQ_THR_IRQ_STATUS);
> > +
> > +   if (task->task_state == TASK_STATE_DONE) {
> > +   cmdq_thread_resume(thread);
> > +   return 0;
> > +   }
> > +
> > +   if (task->task_state == TASK_STATE_ERROR) {
> > +   dev_err(dev, "task 0x%p error\n", task);
> > +   if (next_task) /* move to next task */
> > +   cmdq_thread_writel(thread, next_task->pa_base,
> > +  CMDQ_THR_CURR_ADDR);
> > +   cmdq_thread_resume(thread);
> > +   return -ECANCELED;
> > +   }
> > +
> > +   /* Task is running, so we force to remove it. */
> > +   dev_err(dev, "task 0x%p timeout or killed\n", task);
> 
> No 'kill' state.

>From CMDQ v8, there is no killed task.
I will rewrite output message.

> > +   task->task_state = TASK_STATE_ERROR;
> > +
> > +   if (prev_task) {
> > +   u64 *prev_va = prev_task->va_base;
> > +   u64 *curr_va = task->va_base;
> > +
> > +   /* copy JUMP instruction */
> > +   prev_va[prev_task->num_cmd - 1] = curr_va[task->num_cmd - 1];
> > +
> > +   cmdq_thread_invalidate_fetched_data(thread);
> > +   } else if (next_task) { /* move to next task */
> > +   cmdq_thread_writel(thread, next_task->pa_base,
> > +  CMDQ_THR_CURR_ADDR);
> > +   }
> 
> Just one statement in 'else if' part. So remove the parentheses.

I think we should keep this parentheses.

Quote from CodingStyle document:

This does not apply if only one branch of a conditional statement is a
single
statement; in the latter case use braces in both branches:

if (condition) {
do_this();

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-30 Thread Horng-Shyang Liao
Hi CK,

Reply inline.

On Mon, 2016-05-30 at 14:49 +0800, CK Hu wrote:
> Hi, HS:
> 
> Some comments inline.
> 
> On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
...
> > +static void cmdq_thread_irq_handler(struct cmdq *cmdq, int tid)
> > +{
> > +   struct cmdq_thread *thread = >thread[tid];
> > +   unsigned long flags = 0L;
> > +   u32 irq_flag;
> > +
> > +   spin_lock_irqsave(>exec_lock, flags);
> > +
> > +   irq_flag = cmdq_thread_readl(thread, CMDQ_THR_IRQ_STATUS);
> > +   cmdq_thread_writel(thread, ~irq_flag, CMDQ_THR_IRQ_STATUS);
> > +
> > +   /*
> > +* Another CPU core could run "release task" right before we acquire
> > +* the spin lock, and thus reset / disable this GCE thread, so we
> > +* need to check the enable bit of this GCE thread.
> > +*/
> > +   if (!(cmdq_thread_readl(thread, CMDQ_THR_ENABLE_TASK) &
> > + CMDQ_THR_ENABLED))
> > +   irq_flag = 0;
> 
> These three statement (clear irq flag and detect thread enable) can be
> moved into cmdq_handle_error_done() and the duplicated part in
> cmdq_task_handle_error_result() can be removed. Even though
> cmdq_task_handle_error_result() need not check thread enable, it would
> not influence the flow.

Will do.

> > +
> > +   cmdq_handle_error_done(cmdq, thread, irq_flag);
> > +   spin_unlock_irqrestore(>exec_lock, flags);
> > +}
...
> > +static int cmdq_task_handle_error_result(struct cmdq_task *task)
> > +{
> > +   struct cmdq *cmdq = task->cmdq;
> > +   struct device *dev = cmdq->dev;
> > +   struct cmdq_thread *thread = task->thread;
> > +   struct cmdq_task *next_task, *prev_task;
> > +   u32 irq_flag;
> > +
> > +   /* suspend GCE thread to ensure consistency */
> > +   WARN_ON(cmdq_thread_suspend(cmdq, thread) < 0);
> > +
> > +   /* ISR has handled this error task */
> > +   if (task->task_state == TASK_STATE_ERROR) {
> > +   next_task = list_first_entry_or_null(>task_busy_list,
> > +   struct cmdq_task, list_entry);
> > +   if (next_task) /* move to next task */
> > +   cmdq_thread_writel(thread, next_task->pa_base,
> > +  CMDQ_THR_CURR_ADDR);
> > +   cmdq_thread_resume(thread);
> > +   return -ECANCELED;
> > +   }
> > +
> > +   /*
> > +* Save next_task and prev_task in advance
> > +* since cmdq_handle_error_done will remove list_entry.
> > +*/
> > +   next_task = prev_task = NULL;
> > +   if (task->list_entry.next != >task_busy_list)
> > +   next_task = list_next_entry(task, list_entry);
> > +   if (task->list_entry.prev != >task_busy_list)
> > +   prev_task = list_prev_entry(task, list_entry);
> 
> I think there is always no previous task because task order in
> thread->task_busy_list is the same as in cmdq->task_release_wq. So each
> task processed by release work should be the first item in
> thread->task_busy_list or be removed from thread->task_busy_list.

Will remove previous task.

> > +
> > +   /*
> > +* Although IRQ is disabled, GCE continues to execute.
> > +* It may have pending IRQ before GCE thread is suspended,
> > +* so check this condition again.
> > +*/
> > +   irq_flag = cmdq_thread_readl(thread, CMDQ_THR_IRQ_STATUS);
> > +   cmdq_handle_error_done(cmdq, thread, irq_flag);
> > +   cmdq_thread_writel(thread, ~irq_flag, CMDQ_THR_IRQ_STATUS);
> > +
> > +   if (task->task_state == TASK_STATE_DONE) {
> > +   cmdq_thread_resume(thread);
> > +   return 0;
> > +   }
> > +
> > +   if (task->task_state == TASK_STATE_ERROR) {
> > +   dev_err(dev, "task 0x%p error\n", task);
> > +   if (next_task) /* move to next task */
> > +   cmdq_thread_writel(thread, next_task->pa_base,
> > +  CMDQ_THR_CURR_ADDR);
> > +   cmdq_thread_resume(thread);
> > +   return -ECANCELED;
> > +   }
> > +
> > +   /* Task is running, so we force to remove it. */
> > +   dev_err(dev, "task 0x%p timeout or killed\n", task);
> 
> No 'kill' state.

>From CMDQ v8, there is no killed task.
I will rewrite output message.

> > +   task->task_state = TASK_STATE_ERROR;
> > +
> > +   if (prev_task) {
> > +   u64 *prev_va = prev_task->va_base;
> > +   u64 *curr_va = task->va_base;
> > +
> > +   /* copy JUMP instruction */
> > +   prev_va[prev_task->num_cmd - 1] = curr_va[task->num_cmd - 1];
> > +
> > +   cmdq_thread_invalidate_fetched_data(thread);
> > +   } else if (next_task) { /* move to next task */
> > +   cmdq_thread_writel(thread, next_task->pa_base,
> > +  CMDQ_THR_CURR_ADDR);
> > +   }
> 
> Just one statement in 'else if' part. So remove the parentheses.

I think we should keep this parentheses.

Quote from CodingStyle document:

This does not apply if only one branch of a conditional statement is a
single
statement; in the latter case use braces in both branches:

if (condition) {
do_this();

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-30 Thread CK Hu
Hi, HS:

Some comments inline.

On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help read/write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao 
> Signed-off-by: CK Hu 
> ---
>  drivers/soc/mediatek/Kconfig|  10 +
>  drivers/soc/mediatek/Makefile   |   1 +
>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> 
>  include/soc/mediatek/cmdq.h | 197 +
>  4 files changed, 1151 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
>  create mode 100644 include/soc/mediatek/cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index 0a4ea80..c4ad75c 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -1,6 +1,16 @@
>  #
>  # MediaTek SoC drivers
>  #
> +config MTK_CMDQ
> + bool "MediaTek CMDQ Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select MTK_INFRACFG
> + help
> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +   driver. The CMDQ is used to help read/write registers with critical
> +   time limitation, such as updating display configuration during the
> +   vblank.
> +
>  config MTK_INFRACFG
>   bool "MediaTek INFRACFG Support"
>   depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..f7397ef 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
>  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
> new file mode 100644
> index 000..e9d6e1c
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-cmdq.c
> @@ -0,0 +1,943 @@
> +/*
> + * Copyright (c) 2015 MediaTek Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define CMDQ_INITIAL_CMD_BLOCK_SIZE  PAGE_SIZE
> +#define CMDQ_INST_SIZE   8 /* instruction is 64-bit */
> +#define CMDQ_TIMEOUT_MS  1000
> +#define CMDQ_IRQ_MASK0x
> +#define CMDQ_DRIVER_DEVICE_NAME  "mtk_cmdq"
> +#define CMDQ_CLK_NAME"gce"
> +
> +#define CMDQ_CURR_IRQ_STATUS 0x010
> +#define CMDQ_CURR_LOADED_THR 0x018
> +#define CMDQ_THR_SLOT_CYCLES 0x030
> +
> +#define CMDQ_THR_BASE0x100
> +#define CMDQ_THR_SHIFT   0x080
> +#define CMDQ_THR_WARM_RESET  0x00
> +#define CMDQ_THR_ENABLE_TASK 0x04
> +#define CMDQ_THR_SUSPEND_TASK0x08
> +#define CMDQ_THR_CURR_STATUS 0x0c
> +#define CMDQ_THR_IRQ_STATUS  0x10
> +#define CMDQ_THR_IRQ_ENABLE  0x14
> +#define CMDQ_THR_CURR_ADDR   0x20
> +#define CMDQ_THR_END_ADDR0x24
> +#define CMDQ_THR_CFG 0x40
> +
> +#define CMDQ_THR_ENABLED 0x1
> +#define CMDQ_THR_DISABLED0x0
> +#define CMDQ_THR_SUSPEND 0x1
> +#define CMDQ_THR_RESUME  0x0
> +#define CMDQ_THR_STATUS_SUSPENDEDBIT(1)
> +#define CMDQ_THR_DO_WARM_RESET   BIT(0)
> +#define CMDQ_THR_ACTIVE_SLOT_CYCLES  0x3200
> +#define CMDQ_THR_PRIORITY3
> +#define CMDQ_THR_IRQ_DONE0x1
> +#define CMDQ_THR_IRQ_ERROR   0x12
> +#define CMDQ_THR_IRQ_EN  0x13 /* done + error */
> +#define CMDQ_THR_IRQ_MASK0x13
> +#define CMDQ_THR_EXECUTING   BIT(31)
> +
> +#define CMDQ_ARG_A_WRITE_MASK0x
> +#define CMDQ_SUBSYS_MASK 0x1f
> +#define CMDQ_OP_CODE_MASK0xff00
> +
> +#define CMDQ_OP_CODE_SHIFT   24
> +#define CMDQ_SUBSYS_SHIFT16
> +
> +#define 

Re: [PATCH v8 2/3] CMDQ: Mediatek CMDQ driver

2016-05-30 Thread CK Hu
Hi, HS:

Some comments inline.

On Mon, 2016-05-30 at 11:19 +0800, HS Liao wrote:
> This patch is first version of Mediatek Command Queue(CMDQ) driver. The
> CMDQ is used to help read/write registers with critical time limitation,
> such as updating display configuration during the vblank. It controls
> Global Command Engine (GCE) hardware to achieve this requirement.
> Currently, CMDQ only supports display related hardwares, but we expect
> it can be extended to other hardwares for future requirements.
> 
> Signed-off-by: HS Liao 
> Signed-off-by: CK Hu 
> ---
>  drivers/soc/mediatek/Kconfig|  10 +
>  drivers/soc/mediatek/Makefile   |   1 +
>  drivers/soc/mediatek/mtk-cmdq.c | 943 
> 
>  include/soc/mediatek/cmdq.h | 197 +
>  4 files changed, 1151 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mtk-cmdq.c
>  create mode 100644 include/soc/mediatek/cmdq.h
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index 0a4ea80..c4ad75c 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -1,6 +1,16 @@
>  #
>  # MediaTek SoC drivers
>  #
> +config MTK_CMDQ
> + bool "MediaTek CMDQ Support"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + select MTK_INFRACFG
> + help
> +   Say yes here to add support for the MediaTek Command Queue (CMDQ)
> +   driver. The CMDQ is used to help read/write registers with critical
> +   time limitation, such as updating display configuration during the
> +   vblank.
> +
>  config MTK_INFRACFG
>   bool "MediaTek INFRACFG Support"
>   depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 12998b0..f7397ef 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq.o
>  obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
>  obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
>  obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
> diff --git a/drivers/soc/mediatek/mtk-cmdq.c b/drivers/soc/mediatek/mtk-cmdq.c
> new file mode 100644
> index 000..e9d6e1c
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-cmdq.c
> @@ -0,0 +1,943 @@
> +/*
> + * Copyright (c) 2015 MediaTek Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define CMDQ_INITIAL_CMD_BLOCK_SIZE  PAGE_SIZE
> +#define CMDQ_INST_SIZE   8 /* instruction is 64-bit */
> +#define CMDQ_TIMEOUT_MS  1000
> +#define CMDQ_IRQ_MASK0x
> +#define CMDQ_DRIVER_DEVICE_NAME  "mtk_cmdq"
> +#define CMDQ_CLK_NAME"gce"
> +
> +#define CMDQ_CURR_IRQ_STATUS 0x010
> +#define CMDQ_CURR_LOADED_THR 0x018
> +#define CMDQ_THR_SLOT_CYCLES 0x030
> +
> +#define CMDQ_THR_BASE0x100
> +#define CMDQ_THR_SHIFT   0x080
> +#define CMDQ_THR_WARM_RESET  0x00
> +#define CMDQ_THR_ENABLE_TASK 0x04
> +#define CMDQ_THR_SUSPEND_TASK0x08
> +#define CMDQ_THR_CURR_STATUS 0x0c
> +#define CMDQ_THR_IRQ_STATUS  0x10
> +#define CMDQ_THR_IRQ_ENABLE  0x14
> +#define CMDQ_THR_CURR_ADDR   0x20
> +#define CMDQ_THR_END_ADDR0x24
> +#define CMDQ_THR_CFG 0x40
> +
> +#define CMDQ_THR_ENABLED 0x1
> +#define CMDQ_THR_DISABLED0x0
> +#define CMDQ_THR_SUSPEND 0x1
> +#define CMDQ_THR_RESUME  0x0
> +#define CMDQ_THR_STATUS_SUSPENDEDBIT(1)
> +#define CMDQ_THR_DO_WARM_RESET   BIT(0)
> +#define CMDQ_THR_ACTIVE_SLOT_CYCLES  0x3200
> +#define CMDQ_THR_PRIORITY3
> +#define CMDQ_THR_IRQ_DONE0x1
> +#define CMDQ_THR_IRQ_ERROR   0x12
> +#define CMDQ_THR_IRQ_EN  0x13 /* done + error */
> +#define CMDQ_THR_IRQ_MASK0x13
> +#define CMDQ_THR_EXECUTING   BIT(31)
> +
> +#define CMDQ_ARG_A_WRITE_MASK0x
> +#define CMDQ_SUBSYS_MASK 0x1f
> +#define CMDQ_OP_CODE_MASK0xff00
> +
> +#define CMDQ_OP_CODE_SHIFT   24
> +#define CMDQ_SUBSYS_SHIFT16
> +
> +#define CMDQ_WRITE_ENABLE_MASK