>-----Original Message-----
>From: Yong Wang [mailto:[email protected]]
>Sent: Wednesday, November 24, 2010 2:15 PM
>To: Rudramuni, Vishwesh M; Brown, Len; Anvin, H Peter
>Cc: [email protected]; Bhimarao, Vijay; Muralidhar, Rajeev D; Seshadri,
>Harinarayanan
>Subject: Re: [Meego-kernel] [Meego-Kernel][PATCH 0/3] intel idle driver with
>s0ix hooks
>
>On Wed, Nov 24, 2010 at 09:39:18AM +0530, Rudramuni, Vishwesh M wrote:
>
>First of all, it is customary to send out the entire patch series rather
>than only those that you modified when you come up with a new version.
>In addition, it would be better to name your new patch series [PATCH v2]
>and have a short changelog in the very beginning outlining what changes
>you made.
>
>> diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
>
>> @@ -166,6 +172,24 @@ static struct cpuidle_state
>atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
>>                 .power_usage = 150,
>>                 .target_residency = 4000,
>
>Are you sure C6 has longer target residency than S0ix? What code base is
>your patch against?

I have not changed anything here. Its default set to this.

>
>>                 .enter = &intel_idle },
>> +       { /* S0i1 State*/
>> +               .name = "ATM-S0i1",
>> +               .desc = "MWAIT 0x52",
>> +               .driver_data = (void *) 0x50,
>> +               .flags = CPUIDLE_FLAG_TIME_VALID,
>> +               .exit_latency = 250,
>> +               .power_usage = 150,
>> +               .target_residency = 1000,
>> +               .enter = soc_s0i1_idle },
>> +       { /* S0i3 State*/
>> +               .name = "ATM-S0i3",
>> +               .desc = "MWAIT 0x52",
>> +               .driver_data = (void *) 0x60,
>> +               .flags = CPUIDLE_FLAG_TIME_VALID,
>> +               .exit_latency = 300,
>> +               .power_usage = 150,
>> +               .target_residency = 1200,
>> +               .enter = soc_s0i3_idle }
>>  };
>
>> +static int soc_s0i1_idle(struct cpuidle_device *dev,
>> +                       struct cpuidle_state *state)
>> +{
>> +       int cpu = smp_processor_id();
>> +       struct cpuidle_state *next_state;
>> +       int ret;
>> +
>> +       /* we don't support S0i1 in moorestown , fallback to C6 */
>> +       if (__mrst_cpu_chip != MRST_CPU_CHIP_PENWELL) {
>> +               next_state = &dev->states[4];
>
>Why to fall back to C4 instead of C6?
>
This is indeed C6 & not C4!!!

>> +static int soc_s0i3_idle(struct cpuidle_device *dev,
>> +                       struct cpuidle_state *state)
>> +{
>> +       unsigned long eax = (unsigned long)cpuidle_get_statedata(state);
>> +       ktime_t kt_before, kt_after;
>> +       s64 usec_delta;
>> +       int cpu = smp_processor_id();
>> +       struct cpuidle_state *next_state;
>> +       int ret;
>> +
>
>Here you also need to fall back to plain C states like below. Otherwise,
>it won't work on other Atom based platforms without S0ix support. Keep
>in mind that your code does not only run on mfld and mrst.
>
>       if (__mrst_cpu_chip != MRST_CPU_CHIP_LINCROFT &&
>           __mrst_cpu_chip != MRST_CPU_CHIP_PENWELL) {
>               fallback...
>       }
>
Will add this.
>> +       if (get_target_idle_state() == MID_S0I3_STATE) {
>> +               if (cpu == 0) {
>> +                       local_irq_disable();
>> +                       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
>> +                       &cpu);
>> +
>> +                       kt_before = ktime_get_real();
>> +
>> +                       stop_critical_timings();
>> +#ifndef MODULE
>> +       trace_power_start(POWER_CSTATE, (eax >> 4) + 1);
>> +#endif
>> +                       /* mwait will be called inside mid_s0i3_enter() */
>> +                       mid_s0i3_enter();
>> +
>> +                       start_critical_timings();
>> +
>> +                       kt_after = ktime_get_real();
>> +                       usec_delta =
>> +                               ktime_to_us(ktime_sub(kt_after, kt_before));
>> +
>> +                       local_irq_enable();
>> +
>> +                       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
>> +                       &cpu);
>> +
>> +                       return usec_delta;
>> +               }
>> +       }
>> +
>> +       next_state = &dev->states[4];
>> +       ret = intel_idle(dev, next_state);
>> +       dev->last_state = &dev->states[4];
>> +       return ret;
>> +
>> +}
>
>> diff --git a/drivers/idle/intel_idle.h b/drivers/idle/intel_idle.h
>
>> +#ifndef CONFIG_INTEL_MID_POWER
>> +static void mid_s0i3_enter(void) { }
>> +static void mid_s0i1_prepare(void) { }
>> +static int get_target_idle_state(void) { return 0; }
>> +#endif
>
>#else? Did you even compile test your patch? Ever?
>
>> +extern void mid_s0i3_enter(void);
>> +extern void mid_s0i1_prepare(void);
>> +extern int get_target_idle_state(void);
>> +#endif
>
Will change it.

>> diff --git a/drivers/idle/intel_s0ix.c b/drivers/idle/intel_s0ix.c
>...
>> +static void mrst_apic_save(struct s0ix_data *dev_p)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < LAPIC_MAX_REGS; i++) {
>> +               lapic_regs_val[i] = apic_read((u32) dev_p->apic_base_v + \
>> +                                       lapic_regs_offset[i]);
>
>apic_read is not used this way. Please take a look at
>arch/x86/kernel/apic/apic.c. Btw, this looks very much like
>lapic_suspend which is the standard suspend callback for apic device.
>Can you reuse that? In addition, this proves again that you did
>not test your code. Please do test before submission.
>
>> +       }
>> +}
>> +
>> +static void mrst_apic_restore(struct s0ix_data *dev_p)
>> +{
>> +       int i;
>> +
>> +       /* TODO: need to revisit this code not sure if we need to restore
>> +        * all Lapic registers after S0ix state
>> +        */
>> +       for (i = 0; i < LAPIC_MAX_REGS; i++) {
>> +               apic_write(lapic_regs_val[i], (u32) (dev_p->apic_base_v + \
>> +                       lapic_regs_offset[i]));
>
>ditto.
>
>> +       }
>> +}
>> +
>

Will look into it.

>> +static int mrst_s0i3_env(struct s0ix_data *dev_p)
>> +{
>...
>> +        dev_p->apic_base_v = ioremap(0xFEE00000, PAGE_SIZE);
>> +        if (dev_p->apic_base_v == NULL) {
>> +               /* Unable to remap.  Use a translation address */
>> +               dev_dbg(&pmu_dev->dev, "mrst_s0i3_env: Unable to remap \
>> +               APIC address\n");
>> +               dev_p->apic_base_v = phys_to_virt(0xFEE00000);
>> +        } else
>> +               dev_dbg(&pmu_dev->dev, "APIC mapped @ %p\n", \
>> +               dev_p->apic_base_v);
>
>You do not need to do this which has been done by kernel. IIRC, this
>will also result in kernel warnings of the same area being mapped for
>multiple times.
>
Will remove this.

>> diff --git a/drivers/idle/intel_s0ix.h b/drivers/idle/intel_s0ix.h
>...
>> +/* MSR definitions needed for save restore */
>> +#define IA32_MTRRCAP_MSR               254
>
>You can find this defined as MSR_MTRRcap in msr.h as well.
>
>> +
>> +/* MSR definitions */
>> +#define WAKE_VECTOR_OFFSET             24
>> +#define WAKE_VECTOR_LENGTH             8
>> +
>> +/* Variable MTTR MSR's */
>> +#define MTRRphysBase0                  512
>> +
>
>You can find this defined as MTRRphysBase_MSR in <asm/mtrr.h>.
>
>> +/* CAP_MSR definitions */
>> +#define MTRR_FIXED                     0x100
>> +
>> +/* 11 MTTR's of 64 bits each */
>> +#define MTRR_FIXED_SIZE                        (11 * 8)
>
>Looks like most of the mtrr save/restore code in suspend/resume path
>can be eliminated by reusing the existing code under
>arch/x86/kernel/cpu/mtrr.
>
>> +struct task_state_structure {
>> +       u16 prev_task_link;     /* Offset = 0;  */
>> +       u16 reserved_0;         /*  2 */
>> +       u32 esp0;               /* 4 */
>> +       u16 ss0;                /* 8 */
>> +       u16 reserved_1;         /*  10 */
>> +       u32 esp1;               /*  12 */
>> +       u16 ss1;                /*  16 */
>> +       u16 reserved_2;         /*  18 */
>> +       u32 esp2;               /*  20 */
>> +       u16 ss2;                /*  24 */
>> +       u16 reserved_3;         /*  26 */
>> +       u32 cr3;                /* 28 */
>> +       u32 eip;                /*  32 */
>> +       u32 eflags;             /*  36 */
>> +       u32 eax;                /*  40 */
>> +       u32 ecx;                /*  44 */
>> +       u32 edx;                /*  48 */
>> +       u32 ebx;                /*  52 */
>> +       u32 esp;                /*  56 */
>> +       u32 ebp;                /*  60 */
>> +       u32 esi;                /*  64 */
>> +       u32 edi;                /*  68 */
>> +       u16 es;                 /*  72 */
>> +       u16 reserved_4;         /*  74 */
>> +       u16 cs;                 /*  76 */
>> +       u16 reserved_5;         /*  78 */
>> +       u16 ss;                 /*  80 */
>> +       u16 reserved_6;         /*  82 */
>> +       u16 ds;                 /*  84 */
>> +       u16 reserved_7;         /* 86 */
>> +       u16 fs;                 /*  88 */
>> +       u16 reserved_8;         /*  90 */
>> +       u16 gs;                 /*  92 */
>> +       u16 reserved_9;         /*  94 */
>> +       u16 ldt_sel;            /*  96 */
>> +       u16 reserved_10;        /*  98 */
>> +       u16 reserved_11;        /*  100 */
>> +       u16 io_map_base;        /*  102 */
>> +       u8 io_map[IO_MAP_SIZE]; /*  Rounds up to 128 bytes */
>> +};
>
>Why is this still here? Won't you reuse 'struct x86_hw_tss' in
><asm/processor.h>?
>
>> +
>> +struct dt_entry_bit {
>> +       u16 limit_15_0;
>> +       u16 base_15_0;
>> +       u8 base_23_16;
>> +       u8 type;
>> +       unsigned limit_19_16:4;
>> +       unsigned attr:4;
>> +       u8 base_31_24;
>> +};
>> +
>> +union dt_entry {
>> +       u32 d[2];
>> +       struct dt_entry_bit b;
>> +};
>> +
>
>Why are these still here? Won't you reuse 'struct desc_struct' in
><asm/desc.h>?

We had some issues using the linux tss. All the validation till now is done
With code & it would result in lot more debug with linux tss. I will work
On the linux tss but until then will retain this code.

>
>> diff --git a/drivers/idle/intel_s0ix_resume.S
>b/drivers/idle/intel_s0ix_resume.S
>...
>> +
>> +#ifdef CONFIG_X86_PAE
>> +#define RSM_CR3_VAL                    0x70
>> +#else
>> +#define RSM_CR3_VAL                    0x50
>> +#endif
>
>Looks like your code still runs in both PAE and non-PAE modes. Is PAE a
>hard requirement? If not, please remove the dependency on X86_PAE.
>Otherwise, please clean up all non-PAE code.
>

Will remove this.
>-Yong

_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to