Subject: [FYI/RFC] cell: setting up SMM_HID It turns out that the page sizes for an SPE are not controlled by HID6 but rather by SMM_HID in the hypervisor register space (priv1) of each SPE. Unfortunately, the firmware does not set these up so far (even the one that does set up HID6), so we have to do it ourselves. This is not the real solution, since we cannot simply hardcode this when the firmware might change. Need some discussion with the firmware developers about this. Cc: Hartmut Penner Signed-off-by: Arnd Bergmann --- Index: linus-2.6/arch/powerpc/platforms/cell/spu_base.c =================================================================== --- linus-2.6.orig/arch/powerpc/platforms/cell/spu_base.c +++ linus-2.6/arch/powerpc/platforms/cell/spu_base.c @@ -682,11 +682,14 @@ static int __init create_spu(struct devi spu->nid = of_node_to_nid(spe); if (spu->nid == -1) spu->nid = 0; + spin_lock_init(&spu->register_lock); + spu_mfc_sdr_set(spu, mfspr(SPRN_SDR1)); spu_mfc_sr1_set(spu, 0x33); - mutex_lock(&spu_mutex); + spu_smm_pgsz_set(spu, 0x2); + mutex_lock(&spu_mutex); spu->number = number++; ret = spu_request_irqs(spu); if (ret) Index: linus-2.6/arch/powerpc/platforms/cell/spu_priv1_mmio.c =================================================================== --- linus-2.6.orig/arch/powerpc/platforms/cell/spu_priv1_mmio.c +++ linus-2.6/arch/powerpc/platforms/cell/spu_priv1_mmio.c @@ -109,6 +109,15 @@ static u64 mfc_tclass_id_get(struct spu return in_be64(&spu->priv1->mfc_tclass_id_RW); } +static void smm_pgsz_set(struct spu *spu, u64 pgsz) +{ + u64 smm_hid; + smm_hid = in_be64(&spu->priv1->smm_hid); + smm_hid &= ~(0xfull << 60); + smm_hid |= pgsz << 60; + out_be64(&spu->priv1->smm_hid, smm_hid); +} + static void tlb_invalidate(struct spu *spu) { out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); Index: linus-2.6/include/asm-powerpc/spu_priv1.h =================================================================== --- linus-2.6.orig/include/asm-powerpc/spu_priv1.h +++ linus-2.6/include/asm-powerpc/spu_priv1.h @@ -42,6 +42,7 @@ struct spu_priv1_ops u64 (*mfc_sr1_get) (struct spu *spu); void (*mfc_tclass_id_set) (struct spu *spu, u64 tclass_id); u64 (*mfc_tclass_id_get) (struct spu *spu); + void (*smm_pgsz_set) (struct spu *spu, u64 pgsz); void (*tlb_invalidate) (struct spu *spu); void (*resource_allocation_groupID_set) (struct spu *spu, u64 id); u64 (*resource_allocation_groupID_get) (struct spu *spu); @@ -142,6 +143,12 @@ spu_mfc_tclass_id_get (struct spu *spu) } static inline void +spu_smm_pgsz_set (struct spu *spu, u64 pgsz) +{ + spu_priv1_ops->smm_pgsz_set(spu, pgsz); +} + +static inline void spu_tlb_invalidate (struct spu *spu) { spu_priv1_ops->tlb_invalidate(spu);