#include <asm/arch/ap20.h>
 #include <asm/arch/clk_rst.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/fuse.h>
+#include <asm/arch/gp_padctrl.h>
 #include <asm/arch/pmc.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/scu.h>
 #include <common.h>
 
+int tegra_get_chip_type(void)
+{
+       struct apb_misc_gp_ctlr *gp;
+       struct fuse_regs *fuse = (struct fuse_regs *)TEGRA2_FUSE_BASE;
+       uint tegra_sku_id, rev;
+
+       /*
+        * This is undocumented, Chip ID is bits 15:8 of the register
+        * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for
+        * Tegra30
+        */
+       gp = (struct apb_misc_gp_ctlr *)TEGRA2_APB_MISC_GP_BASE;
+       rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;
+
+       tegra_sku_id = readl(&fuse->sku_info) & 0xff;
+
+       switch (rev) {
+       case CHIPID_TEGRA2:
+               switch (tegra_sku_id) {
+               case SKU_ID_T20:
+                       return TEGRA_SOC_T20;
+               case SKU_ID_T25SE:
+               case SKU_ID_AP25:
+               case SKU_ID_T25:
+               case SKU_ID_AP25E:
+               case SKU_ID_T25E:
+                       return TEGRA_SOC_T25;
+               }
+               break;
+       }
+       /* unknown sku id */
+       return TEGRA_SOC_UNKNOWN;
+}
+
 /* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */
 static int ap20_cpu_is_cortexa9(void)
 {
 
 
 /* This is the main entry into U-Boot, used by the Cortex-A9 */
 extern void _start(void);
+
+/**
+ * Works out the SOC type used for clocks settings
+ *
+ * @return     SOC type - see TEGRA_SOC...
+ */
+int tegra_get_chip_type(void);
 
        u32     memcomp;        /* 0xD4: APB_MISC_GP_MEMCOMPPADCTRL */
 };
 
+/* bit fields definitions for APB_MISC_GP_HIDREV register */
+#define HIDREV_CHIPID_SHIFT            8
+#define HIDREV_CHIPID_MASK             (0xff << HIDREV_CHIPID_SHIFT)
+#define HIDREV_MAJORPREV_SHIFT         4
+#define HIDREV_MAJORPREV_MASK          (0xf << HIDREV_MAJORPREV_SHIFT)
+
+/* CHIPID field returned from APB_MISC_GP_HIDREV register */
+#define CHIPID_TEGRA2                          0x20
+
 #endif
 
 #define NV_PA_GPIO_BASE                0x6000D000
 #define NV_PA_EVP_BASE         0x6000F000
 #define NV_PA_APB_MISC_BASE    0x70000000
+#define TEGRA2_APB_MISC_GP_BASE        (NV_PA_APB_MISC_BASE + 0x0800)
 #define NV_PA_APB_UARTA_BASE   (NV_PA_APB_MISC_BASE + 0x6000)
 #define NV_PA_APB_UARTB_BASE   (NV_PA_APB_MISC_BASE + 0x6040)
 #define NV_PA_APB_UARTC_BASE   (NV_PA_APB_MISC_BASE + 0x6200)
 struct timerus {
        unsigned int cntr_1us;
 };
+
+/* Address at which WB code runs, it must not overlap Bootrom's IRAM usage */
+#define AP20_WB_RUN_ADDRESS    0x40020000
+
+/* These are the available SKUs (product types) for Tegra */
+enum {
+       SKU_ID_T20              = 0x8,
+       SKU_ID_T25SE            = 0x14,
+       SKU_ID_AP25             = 0x17,
+       SKU_ID_T25              = 0x18,
+       SKU_ID_AP25E            = 0x1b,
+       SKU_ID_T25E             = 0x1c,
+};
+
+/* These are the SOC categories that affect clocking */
+enum {
+       TEGRA_SOC_T20,
+       TEGRA_SOC_T25,
+
+       TEGRA_SOC_COUNT,
+       TEGRA_SOC_UNKNOWN       = -1,
+};
+
 #else  /* __ASSEMBLY__ */
 #define PRM_RSTCTRL            TEGRA2_PMC_BASE
 #endif