Commit 43835aac4803d459dd73fabce09b27a826a381d7

Authored by Detlev Zundel
1 parent e8143e72e1
Exists in master and in 55 other branches 8qm-imx_v2020.04_5.4.70_2.3.0, emb_lf_v2022.04, emb_lf_v2023.04, imx_v2015.04_4.1.15_1.0.0_ga, pitx_8mp_lf_v2020.04, smarc-8m-android-10.0.0_2.6.0, smarc-8m-android-11.0.0_2.0.0, smarc-8mp-android-11.0.0_2.0.0, smarc-emmc-imx_v2014.04_3.10.53_1.1.0_ga, smarc-emmc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx-l5.0.0_1.0.0-ga, smarc-imx6_v2018.03_4.14.98_2.0.0_ga, smarc-imx7_v2017.03_4.9.11_1.0.0_ga, smarc-imx7_v2018.03_4.14.98_2.0.0_ga, smarc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx_v2015.04_4.1.15_1.0.0_ga, smarc-imx_v2017.03_4.9.11_1.0.0_ga, smarc-imx_v2017.03_4.9.88_2.0.0_ga, smarc-imx_v2017.03_o8.1.0_1.3.0_8m, smarc-imx_v2018.03_4.14.78_1.0.0_ga, smarc-m6.0.1_2.1.0-ga, smarc-n7.1.2_2.0.0-ga, smarc-rel_imx_4.1.15_2.0.0_ga, smarc_8m-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8m-imx_v2019.04_4.19.35_1.1.0, smarc_8m_00d0-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2019.04_4.19.35_1.1.0, smarc_8mm-imx_v2020.04_5.4.24_2.1.0, smarc_8mp_lf_v2020.04, smarc_8mq-imx_v2020.04_5.4.24_2.1.0, smarc_8mq_lf_v2020.04, ti-u-boot-2015.07, u-boot-2013.01.y, v2013.10, v2013.10-smarct33, v2013.10-smartmen, v2014.01, v2014.04, v2014.04-smarct33, v2014.04-smarct33-emmc, v2014.04-smartmen, v2014.07, v2014.07-smarct33, v2014.07-smartmen, v2015.07-smarct33, v2015.07-smarct33-emmc, v2015.07-smarct4x, v2016.05-dlt, v2016.05-smarct3x, v2016.05-smarct3x-emmc, v2016.05-smarct4x, v2017.01-smarct3x, v2017.01-smarct3x-emmc, v2017.01-smarct4x

Added interrupt handling capabilities for mpc5xxx processors.

Also added Linux like BUG() macros.

Showing 3 changed files with 342 additions and 15 deletions Side-by-side Diff

cpu/mpc5xxx/interrupts.c
1 1 /*
  2 + * (C) Copyright 2006
  3 + * Detlev Zundel, DENX Software Engineering, dzu@denx.de
  4 + *
2 5 * (C) Copyright -2003
3 6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 7 *
5 8  
6 9  
7 10  
8 11  
... ... @@ -24,18 +27,212 @@
24 27 * MA 02111-1307 USA
25 28 */
26 29  
27   -/*
28   - * interrupts.c - just enough support for the decrementer/timer
  30 +/* this section was ripped out of arch/ppc/syslib/mpc52xx_pic.c in the
  31 + * Linux 2.6 source with the following copyright.
  32 + *
  33 + * Based on (well, mostly copied from) the code from the 2.4 kernel by
  34 + * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
  35 + *
  36 + * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
  37 + * Copyright (C) 2003 Montavista Software, Inc
29 38 */
30 39  
31 40 #include <common.h>
32 41 #include <asm/processor.h>
  42 +#include <asm/io.h>
33 43 #include <command.h>
34 44  
35   -int interrupt_init_cpu (ulong *decrementer_count)
  45 +struct irq_action {
  46 + interrupt_handler_t *handler;
  47 + void *arg;
  48 + ulong count;
  49 +};
  50 +
  51 +static struct irq_action irq_handlers[NR_IRQS];
  52 +
  53 +static struct mpc5xxx_intr *intr;
  54 +static struct mpc5xxx_sdma *sdma;
  55 +
  56 +static void mpc5xxx_ic_disable(unsigned int irq)
36 57 {
  58 + u32 val;
  59 +
  60 + if (irq == MPC5XXX_IRQ0) {
  61 + val = in_be32(&intr->ctrl);
  62 + val &= ~(1 << 11);
  63 + out_be32(&intr->ctrl, val);
  64 + } else if (irq < MPC5XXX_IRQ1) {
  65 + BUG();
  66 + } else if (irq <= MPC5XXX_IRQ3) {
  67 + val = in_be32(&intr->ctrl);
  68 + val &= ~(1 << (10 - (irq - MPC5XXX_IRQ1)));
  69 + out_be32(&intr->ctrl, val);
  70 + } else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
  71 + val = in_be32(&intr->main_mask);
  72 + val |= 1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE));
  73 + out_be32(&intr->main_mask, val);
  74 + } else if (irq < MPC5XXX_PERP_IRQ_BASE) {
  75 + val = in_be32(&sdma->IntMask);
  76 + val |= 1 << (irq - MPC5XXX_SDMA_IRQ_BASE);
  77 + out_be32(&sdma->IntMask, val);
  78 + } else {
  79 + val = in_be32(&intr->per_mask);
  80 + val |= 1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE));
  81 + out_be32(&intr->per_mask, val);
  82 + }
  83 +}
  84 +
  85 +static void mpc5xxx_ic_enable(unsigned int irq)
  86 +{
  87 + u32 val;
  88 +
  89 + if (irq == MPC5XXX_IRQ0) {
  90 + val = in_be32(&intr->ctrl);
  91 + val |= 1 << 11;
  92 + out_be32(&intr->ctrl, val);
  93 + } else if (irq < MPC5XXX_IRQ1) {
  94 + BUG();
  95 + } else if (irq <= MPC5XXX_IRQ3) {
  96 + val = in_be32(&intr->ctrl);
  97 + val |= 1 << (10 - (irq - MPC5XXX_IRQ1));
  98 + out_be32(&intr->ctrl, val);
  99 + } else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
  100 + val = in_be32(&intr->main_mask);
  101 + val &= ~(1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE)));
  102 + out_be32(&intr->main_mask, val);
  103 + } else if (irq < MPC5XXX_PERP_IRQ_BASE) {
  104 + val = in_be32(&sdma->IntMask);
  105 + val &= ~(1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
  106 + out_be32(&sdma->IntMask, val);
  107 + } else {
  108 + val = in_be32(&intr->per_mask);
  109 + val &= ~(1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE)));
  110 + out_be32(&intr->per_mask, val);
  111 + }
  112 +}
  113 +
  114 +static void mpc5xxx_ic_ack(unsigned int irq)
  115 +{
  116 + u32 val;
  117 +
  118 + /*
  119 + * Only some irqs are reset here, others in interrupting hardware.
  120 + */
  121 +
  122 + switch (irq) {
  123 + case MPC5XXX_IRQ0:
  124 + val = in_be32(&intr->ctrl);
  125 + val |= 0x08000000;
  126 + out_be32(&intr->ctrl, val);
  127 + break;
  128 + case MPC5XXX_CCS_IRQ:
  129 + val = in_be32(&intr->enc_status);
  130 + val |= 0x00000400;
  131 + out_be32(&intr->enc_status, val);
  132 + break;
  133 + case MPC5XXX_IRQ1:
  134 + val = in_be32(&intr->ctrl);
  135 + val |= 0x04000000;
  136 + out_be32(&intr->ctrl, val);
  137 + break;
  138 + case MPC5XXX_IRQ2:
  139 + val = in_be32(&intr->ctrl);
  140 + val |= 0x02000000;
  141 + out_be32(&intr->ctrl, val);
  142 + break;
  143 + case MPC5XXX_IRQ3:
  144 + val = in_be32(&intr->ctrl);
  145 + val |= 0x01000000;
  146 + out_be32(&intr->ctrl, val);
  147 + break;
  148 + default:
  149 + if (irq >= MPC5XXX_SDMA_IRQ_BASE
  150 + && irq < (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)) {
  151 + out_be32(&sdma->IntPend,
  152 + 1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
  153 + }
  154 + break;
  155 + }
  156 +}
  157 +
  158 +static void mpc5xxx_ic_disable_and_ack(unsigned int irq)
  159 +{
  160 + mpc5xxx_ic_disable(irq);
  161 + mpc5xxx_ic_ack(irq);
  162 +}
  163 +
  164 +static void mpc5xxx_ic_end(unsigned int irq)
  165 +{
  166 + mpc5xxx_ic_enable(irq);
  167 +}
  168 +
  169 +void mpc5xxx_init_irq(void)
  170 +{
  171 + u32 intr_ctrl;
  172 +
  173 + /* Remap the necessary zones */
  174 + intr = (struct mpc5xxx_intr *)(MPC5XXX_ICTL);
  175 + sdma = (struct mpc5xxx_sdma *)(MPC5XXX_SDMA);
  176 +
  177 + /* Disable all interrupt sources. */
  178 + out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
  179 + out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
  180 + out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
  181 + out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
  182 + intr_ctrl = in_be32(&intr->ctrl);
  183 + intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
  184 + 0x00ff0000 | /* IRQ 0-3 level sensitive low active */
  185 + 0x00001000 | /* MEE master external enable */
  186 + 0x00000000 | /* 0 means disable IRQ 0-3 */
  187 + 0x00000001; /* CEb route critical normally */
  188 + out_be32(&intr->ctrl, intr_ctrl);
  189 +
  190 + /* Zero a bunch of the priority settings. */
  191 + out_be32(&intr->per_pri1, 0);
  192 + out_be32(&intr->per_pri2, 0);
  193 + out_be32(&intr->per_pri3, 0);
  194 + out_be32(&intr->main_pri1, 0);
  195 + out_be32(&intr->main_pri2, 0);
  196 +}
  197 +
  198 +int mpc5xxx_get_irq(struct pt_regs *regs)
  199 +{
  200 + u32 status;
  201 + int irq = -1;
  202 +
  203 + status = in_be32(&intr->enc_status);
  204 +
  205 + if (status & 0x00000400) { /* critical */
  206 + irq = (status >> 8) & 0x3;
  207 + if (irq == 2) /* high priority peripheral */
  208 + goto peripheral;
  209 + irq += MPC5XXX_CRIT_IRQ_BASE;
  210 + } else if (status & 0x00200000) { /* main */
  211 + irq = (status >> 16) & 0x1f;
  212 + if (irq == 4) /* low priority peripheral */
  213 + goto peripheral;
  214 + irq += MPC5XXX_MAIN_IRQ_BASE;
  215 + } else if (status & 0x20000000) { /* peripheral */
  216 + peripheral:
  217 + irq = (status >> 24) & 0x1f;
  218 + if (irq == 0) { /* bestcomm */
  219 + status = in_be32(&sdma->IntPend);
  220 + irq = ffs(status) + MPC5XXX_SDMA_IRQ_BASE - 1;
  221 + } else
  222 + irq += MPC5XXX_PERP_IRQ_BASE;
  223 + }
  224 +
  225 + return irq;
  226 +}
  227 +
  228 +/****************************************************************************/
  229 +
  230 +int interrupt_init_cpu(ulong * decrementer_count)
  231 +{
37 232 *decrementer_count = get_tbclk() / CFG_HZ;
38 233  
  234 + mpc5xxx_init_irq();
  235 +
39 236 return (0);
40 237 }
41 238  
42 239  
43 240  
... ... @@ -44,14 +241,32 @@
44 241 /*
45 242 * Handle external interrupts
46 243 */
47   -void
48   -external_interrupt(struct pt_regs *regs)
  244 +void external_interrupt(struct pt_regs *regs)
49 245 {
50   - puts("external_interrupt (oops!)\n");
  246 + int irq, unmask = 1;
  247 +
  248 + irq = mpc5xxx_get_irq(regs);
  249 +
  250 + mpc5xxx_ic_disable_and_ack(irq);
  251 +
  252 + enable_interrupts();
  253 +
  254 + if (irq_handlers[irq].handler != NULL)
  255 + (*irq_handlers[irq].handler) (irq_handlers[irq].arg);
  256 + else {
  257 + printf("\nBogus External Interrupt IRQ %d\n", irq);
  258 + /*
  259 + * turn off the bogus interrupt, otherwise it
  260 + * might repeat forever
  261 + */
  262 + unmask = 0;
  263 + }
  264 +
  265 + if (unmask)
  266 + mpc5xxx_ic_end(irq);
51 267 }
52 268  
53   -void
54   -timer_interrupt_cpu (struct pt_regs *regs)
  269 +void timer_interrupt_cpu(struct pt_regs *regs)
55 270 {
56 271 /* nothing to do here */
57 272 return;
58 273  
59 274  
60 275  
61 276  
62 277  
63 278  
64 279  
65 280  
... ... @@ -63,23 +278,70 @@
63 278 * Install and free a interrupt handler.
64 279 */
65 280  
66   -void
67   -irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
  281 +void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
68 282 {
  283 + if (irq < 0 || irq >= NR_IRQS) {
  284 + printf("irq_install_handler: bad irq number %d\n", irq);
  285 + return;
  286 + }
69 287  
  288 + if (irq_handlers[irq].handler != NULL)
  289 + printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
  290 + (ulong) handler, (ulong) irq_handlers[irq].handler);
  291 +
  292 + irq_handlers[irq].handler = handler;
  293 + irq_handlers[irq].arg = arg;
  294 +
  295 + mpc5xxx_ic_enable(irq);
70 296 }
71 297  
72   -void
73   -irq_free_handler(int vec)
  298 +void irq_free_handler(int irq)
74 299 {
  300 + if (irq < 0 || irq >= NR_IRQS) {
  301 + printf("irq_free_handler: bad irq number %d\n", irq);
  302 + return;
  303 + }
75 304  
  305 + mpc5xxx_ic_disable(irq);
  306 +
  307 + irq_handlers[irq].handler = NULL;
  308 + irq_handlers[irq].arg = NULL;
76 309 }
77 310  
78 311 /****************************************************************************/
79 312  
80   -void
81   -do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
  313 +#if (CONFIG_COMMANDS & CFG_CMD_IRQ)
  314 +void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
82 315 {
83   - puts("IRQ related functions are unimplemented currently.\n");
  316 + int irq, re_enable;
  317 + u32 intr_ctrl;
  318 + char *irq_config[] = { "level sensitive, active high",
  319 + "edge sensitive, rising active edge",
  320 + "edge sensitive, falling active edge",
  321 + "level sensitive, active low"
  322 + };
  323 +
  324 + re_enable = disable_interrupts();
  325 +
  326 + intr_ctrl = in_be32(&intr->ctrl);
  327 + printf("Interrupt configuration:\n");
  328 +
  329 + for (irq = 0; irq <= 3; irq++) {
  330 + printf("IRQ%d: %s\n", irq,
  331 + irq_config[(intr_ctrl >> (22 - 2 * irq)) & 0x3]);
  332 + }
  333 +
  334 + puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n");
  335 +
  336 + for (irq = 0; irq < NR_IRQS; irq++)
  337 + if (irq_handlers[irq].handler != NULL)
  338 + printf("%02d %08lx %08lx %ld\n", irq,
  339 + (ulong) irq_handlers[irq].handler,
  340 + (ulong) irq_handlers[irq].arg,
  341 + irq_handlers[irq].count);
  342 +
  343 + if (re_enable)
  344 + enable_interrupts();
84 345 }
  346 +#endif
... ... @@ -109,6 +109,12 @@
109 109 #define debugX(level,fmt,args...)
110 110 #endif /* DEBUG */
111 111  
  112 +#define BUG() do { \
  113 + printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
  114 + panic("BUG!"); \
  115 +} while (0)
  116 +#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
  117 +
112 118 typedef void (interrupt_handler_t)(void *);
113 119  
114 120 #include <asm/u-boot.h> /* boot information for Linux kernel */
... ... @@ -232,6 +232,65 @@
232 232 #define MPC5XXX_ICTL_PER_STS (MPC5XXX_ICTL + 0x0030)
233 233 #define MPC5XXX_ICTL_BUS_STS (MPC5XXX_ICTL + 0x0038)
234 234  
  235 +#define NR_IRQS 64
  236 +
  237 +/* IRQ mapping - these are our logical IRQ numbers */
  238 +#define MPC5XXX_CRIT_IRQ_NUM 4
  239 +#define MPC5XXX_MAIN_IRQ_NUM 17
  240 +#define MPC5XXX_SDMA_IRQ_NUM 17
  241 +#define MPC5XXX_PERP_IRQ_NUM 23
  242 +
  243 +#define MPC5XXX_CRIT_IRQ_BASE 1
  244 +#define MPC5XXX_MAIN_IRQ_BASE (MPC5XXX_CRIT_IRQ_BASE + MPC5XXX_CRIT_IRQ_NUM)
  245 +#define MPC5XXX_SDMA_IRQ_BASE (MPC5XXX_MAIN_IRQ_BASE + MPC5XXX_MAIN_IRQ_NUM)
  246 +#define MPC5XXX_PERP_IRQ_BASE (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)
  247 +
  248 +#define MPC5XXX_IRQ0 (MPC5XXX_CRIT_IRQ_BASE + 0)
  249 +#define MPC5XXX_SLICE_TIMER_0_IRQ (MPC5XXX_CRIT_IRQ_BASE + 1)
  250 +#define MPC5XXX_HI_INT_IRQ (MPC5XXX_CRIT_IRQ_BASE + 2)
  251 +#define MPC5XXX_CCS_IRQ (MPC5XXX_CRIT_IRQ_BASE + 3)
  252 +
  253 +#define MPC5XXX_IRQ1 (MPC5XXX_MAIN_IRQ_BASE + 1)
  254 +#define MPC5XXX_IRQ2 (MPC5XXX_MAIN_IRQ_BASE + 2)
  255 +#define MPC5XXX_IRQ3 (MPC5XXX_MAIN_IRQ_BASE + 3)
  256 +#define MPC5XXX_RTC_PINT_IRQ (MPC5XXX_MAIN_IRQ_BASE + 5)
  257 +#define MPC5XXX_RTC_SINT_IRQ (MPC5XXX_MAIN_IRQ_BASE + 6)
  258 +#define MPC5XXX_RTC_GPIO_STD_IRQ (MPC5XXX_MAIN_IRQ_BASE + 7)
  259 +#define MPC5XXX_RTC_GPIO_WKUP_IRQ (MPC5XXX_MAIN_IRQ_BASE + 8)
  260 +#define MPC5XXX_TMR0_IRQ (MPC5XXX_MAIN_IRQ_BASE + 9)
  261 +#define MPC5XXX_TMR1_IRQ (MPC5XXX_MAIN_IRQ_BASE + 10)
  262 +#define MPC5XXX_TMR2_IRQ (MPC5XXX_MAIN_IRQ_BASE + 11)
  263 +#define MPC5XXX_TMR3_IRQ (MPC5XXX_MAIN_IRQ_BASE + 12)
  264 +#define MPC5XXX_TMR4_IRQ (MPC5XXX_MAIN_IRQ_BASE + 13)
  265 +#define MPC5XXX_TMR5_IRQ (MPC5XXX_MAIN_IRQ_BASE + 14)
  266 +#define MPC5XXX_TMR6_IRQ (MPC5XXX_MAIN_IRQ_BASE + 15)
  267 +#define MPC5XXX_TMR7_IRQ (MPC5XXX_MAIN_IRQ_BASE + 16)
  268 +
  269 +#define MPC5XXX_SDMA_IRQ (MPC5XXX_PERP_IRQ_BASE + 0)
  270 +#define MPC5XXX_PSC1_IRQ (MPC5XXX_PERP_IRQ_BASE + 1)
  271 +#define MPC5XXX_PSC2_IRQ (MPC5XXX_PERP_IRQ_BASE + 2)
  272 +#define MPC5XXX_PSC3_IRQ (MPC5XXX_PERP_IRQ_BASE + 3)
  273 +#define MPC5XXX_PSC6_IRQ (MPC5XXX_PERP_IRQ_BASE + 4)
  274 +#define MPC5XXX_IRDA_IRQ (MPC5XXX_PERP_IRQ_BASE + 4)
  275 +#define MPC5XXX_FEC_IRQ (MPC5XXX_PERP_IRQ_BASE + 5)
  276 +#define MPC5XXX_USB_IRQ (MPC5XXX_PERP_IRQ_BASE + 6)
  277 +#define MPC5XXX_ATA_IRQ (MPC5XXX_PERP_IRQ_BASE + 7)
  278 +#define MPC5XXX_PCI_CNTRL_IRQ (MPC5XXX_PERP_IRQ_BASE + 8)
  279 +#define MPC5XXX_PCI_SCIRX_IRQ (MPC5XXX_PERP_IRQ_BASE + 9)
  280 +#define MPC5XXX_PCI_SCITX_IRQ (MPC5XXX_PERP_IRQ_BASE + 10)
  281 +#define MPC5XXX_PSC4_IRQ (MPC5XXX_PERP_IRQ_BASE + 11)
  282 +#define MPC5XXX_PSC5_IRQ (MPC5XXX_PERP_IRQ_BASE + 12)
  283 +#define MPC5XXX_SPI_MODF_IRQ (MPC5XXX_PERP_IRQ_BASE + 13)
  284 +#define MPC5XXX_SPI_SPIF_IRQ (MPC5XXX_PERP_IRQ_BASE + 14)
  285 +#define MPC5XXX_I2C1_IRQ (MPC5XXX_PERP_IRQ_BASE + 15)
  286 +#define MPC5XXX_I2C2_IRQ (MPC5XXX_PERP_IRQ_BASE + 16)
  287 +#define MPC5XXX_MSCAN1_IRQ (MPC5XXX_PERP_IRQ_BASE + 17)
  288 +#define MPC5XXX_MSCAN2_IRQ (MPC5XXX_PERP_IRQ_BASE + 18)
  289 +#define MPC5XXX_IR_RX_IRQ (MPC5XXX_PERP_IRQ_BASE + 19)
  290 +#define MPC5XXX_IR_TX_IRQ (MPC5XXX_PERP_IRQ_BASE + 20)
  291 +#define MPC5XXX_XLB_ARB_IRQ (MPC5XXX_PERP_IRQ_BASE + 21)
  292 +#define MPC5XXX_BDLC_IRQ (MPC5XXX_PERP_IRQ_BASE + 22)
  293 +
235 294 /* General Purpose Timers registers */
236 295 #define MPC5XXX_GPT0_ENABLE (MPC5XXX_GPT + 0x0)
237 296 #define MPC5XXX_GPT0_COUNTER (MPC5XXX_GPT + 0x4)