}
 
 #ifndef CONFIG_NAND_SPL
+static inline void use_tlb_cam(u8 idx)
+{
+       int i = idx / 32;
+       int bit = idx % 32;
+
+       gd->used_tlb_cams[i] |= (1 << bit);
+}
+
+static inline void free_tlb_cam(u8 idx)
+{
+       int i = idx / 32;
+       int bit = idx % 32;
+
+       gd->used_tlb_cams[i] &= ~(1 << bit);
+}
+
+void init_used_tlb_cams(void)
+{
+       int i;
+       unsigned int num_cam = mfspr(SPRN_TLB1CFG) & 0xfff;
+
+       for (i = 0; i < ((CONFIG_SYS_NUM_TLBCAMS+31)/32); i++)
+               gd->used_tlb_cams[i] = 0;
+
+       /* walk all the entries */
+       for (i = 0; i < num_cam; i++) {
+               u32 _mas1;
+
+               mtspr(MAS0, FSL_BOOKE_MAS0(1, i, 0));
+
+               asm volatile("tlbre;isync");
+               _mas1 = mfspr(MAS1);
+
+               /* if the entry isn't valid skip it */
+               if ((_mas1 & MAS1_VALID))
+                       use_tlb_cam(i);
+       }
+}
+
+int find_free_tlbcam(void)
+{
+       int i;
+       u32 idx;
+
+       for (i = 0; i < ((CONFIG_SYS_NUM_TLBCAMS+31)/32); i++) {
+               idx = ffz(gd->used_tlb_cams[i]);
+
+               if (idx != 32)
+                       break;
+       }
+
+       idx += i * 32;
+
+       if (idx >= CONFIG_SYS_NUM_TLBCAMS)
+               return -1;
+
+       return idx;
+}
+
 void set_tlb(u8 tlb, u32 epn, u64 rpn,
             u8 perms, u8 wimge,
             u8 ts, u8 esel, u8 tsize, u8 iprot)
 {
        u32 _mas0, _mas1, _mas2, _mas3, _mas7;
 
+       if (tlb == 1)
+               use_tlb_cam(esel);
+
        _mas0 = FSL_BOOKE_MAS0(tlb, esel, 0);
        _mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize);
        _mas2 = FSL_BOOKE_MAS2(epn, wimge);
 {
        u32 _mas0, _mas1, _mas2, _mas3, _mas7;
 
+       free_tlb_cam(esel);
+
        _mas0 = FSL_BOOKE_MAS0(1, esel, 0);
        _mas1 = 0;
        _mas2 = 0;
 
 #define CONFIG_TSECV2
 #endif
 
+/* Number of TLB CAM entries we have on FSL Book-E chips */
+#if defined(CONFIG_E500MC)
+#define CONFIG_SYS_NUM_TLBCAMS 64
+#elif defined(CONFIG_E500)
+#define CONFIG_SYS_NUM_TLBCAMS 16
+#endif
+
 /* Relocation to SDRAM works on all PPC boards */
 #define CONFIG_RELOC_FIXUP_WORKS