void
ReInstall_clock(void (*new_clock_isr)(void *))
{
	uint32_t   isrlevel = 0;
	rtems_irq_connect_data clockIrqConnData;

	rtems_interrupt_disable(isrlevel);
	clockIrqConnData.name = BSP_PIT;
	if ( ! BSP_get_current_rtems_irq_handler(&clockIrqConnData)) {
		printk("Unable to stop system clock\n");
		rtems_fatal_error_occurred(1);
	}

	BSP_remove_rtems_irq_handler (&clockIrqConnData);
	clockIrqConnData.on   = ClockOn;
	clockIrqConnData.off  = ClockOff;
	clockIrqConnData.isOn = ClockIsOn;
	clockIrqConnData.name = BSP_PIT;
	clockIrqConnData.hdl  = new_clock_isr;
	if (!BSP_install_rtems_irq_handler (&clockIrqConnData)) {
		printk("Unable to connect Clock Irq handler\n");
		rtems_fatal_error_occurred(1);
	}
	rtems_interrupt_enable(isrlevel);
}
Exemple #2
0
int BSP_disconnect_clock_handler (void)
{
  if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
     printk("Unable to stop system clock\n");
    rtems_fatal_error_occurred(1);
  }
  return BSP_remove_rtems_irq_handler (&clockIrqData);
}
void Clock_exit(void)
{
    rtems_irq_connect_data clockIrqConnData;

    clockIrqConnData.name = BSP_PIT;
    if (!BSP_get_current_rtems_irq_handler(&clockIrqConnData)) {
      printk("Unable to stop system clock\n");
      rtems_fatal_error_occurred(1);
    }
    BSP_remove_rtems_irq_handler (&clockIrqConnData);
}
Exemple #4
0
int BSP_connect_clock_handler (rtems_irq_hdl hdl)
{
  if (!BSP_get_current_rtems_irq_handler(&clockIrqData)) {
     printk("Unable to get system clock handler\n");
    rtems_fatal_error_occurred(1);
  }
  if (!BSP_remove_rtems_irq_handler (&clockIrqData)) {
   printk("Unable to remove current system clock handler\n");
    rtems_fatal_error_occurred(1);
  }
  /*
   * Reinit structure
   */
  clockIrqData.name = BSP_PERIODIC_TIMER;
  clockIrqData.hdl = (rtems_irq_hdl) hdl;
  clockIrqData.on = (rtems_irq_enable)clockOn;
  clockIrqData.off = (rtems_irq_enable)clockOff;
  clockIrqData.isOn = (rtems_irq_is_enabled)clockIsOn;

  return BSP_install_rtems_irq_handler (&clockIrqData);
}
Exemple #5
0
void xilTemacStart(struct ifnet *ifp)
{
  if( (ifp->if_flags & IFF_RUNNING) == 0 )
  {
    struct XilTemac* xilTemac = ifp->if_softc;
    uint32_t base = xilTemac->iAddr;

    /* Reset plb temac */
    OUT32(base + XTE_DSR_OFFSET, XTE_DSR_RESET_MASK);
    /* Don't have usleep on rtems 4.6
    usleep(1);
    */
    /* @ fastest ppc clock of 500 MHz = 2ns clk */
    uint32_t i = 0;
    for( i = 0; i < 1 * 500; i++) {
    }

    /* Reset hard temac */
    OUT32(base + XTE_CR_OFFSET, XTE_CR_HTRST_MASK);
    /* Don't have usleep on rtems 4.6
    usleep(4);
    */
    for( i = 0; i < 4 * 500; i++) {
    }

    /* Disable the receiver -- no need to disable xmit as we control that ;) */
    uint32_t rxc1 = IN32(base + XTE_ERXC1_OFFSET);
    rxc1 &= ~XTE_ERXC1_RXEN_MASK;
    OUT32(base + XTE_ERXC1_OFFSET, rxc1);

    /* If receiver was receiving a packet when we disabled it, it will be
     * rejected, clear appropriate status bit */
    uint32_t ipisr = IN32(base + XTE_IPISR_OFFSET);
    if( ipisr & XTE_IPXR_RECV_REJECT_MASK ) {
      OUT32(base + XTE_IPISR_OFFSET, XTE_IPXR_RECV_REJECT_MASK);
    }

    /* Setup IPIF interrupt enables */
    uint32_t dier = XTE_DXR_CORE_MASK | XTE_DXR_DPTO_MASK | XTE_DXR_TERR_MASK;
    dier |= XTE_DXR_RECV_FIFO_MASK | XTE_DXR_SEND_FIFO_MASK;
    OUT32(base + XTE_DIER_OFFSET, dier);

    /* Set the mac address */
    xilTemacSetMacAddress( ifp, xilTemac->iArpcom.ac_enaddr);

    /* Set the link speed */
    uint32_t emcfg = IN32(base + XTE_ECFG_OFFSET);
    printk("xiltemacStart, default linkspeed: %08x\n", emcfg);
    emcfg = (emcfg & ~XTE_ECFG_LINKSPD_MASK) | XTE_ECFG_LINKSPD_100;
    OUT32(base + XTE_ECFG_OFFSET, emcfg);

    /* Set phy divisor and enable mdio.  For a plb bus freq of 150MHz (the
       maximum as of Virtex4 Fx), a divisor of 29 gives a mdio clk freq of
       2.5MHz (see Xilinx docs for equation), the maximum in the phy standard.
       For slower plb frequencies, slower mkdio clks will result.  They may not
       be optimal, but they should work.  */
    uint32_t divisor = 29;
    OUT32(base + XTE_EMC_OFFSET, divisor | XTE_EMC_MDIO_MASK);

#if PPC_HAS_CLASSIC_EXCEPTIONS /* old connect code */
    /* Connect isr vector */
    rtems_status_code   sc;
    extern rtems_isr xilTemacIsr( rtems_vector_number aVector );
    sc = opb_intc_set_vector( xilTemacIsr, xilTemac->iIsrVector, &xilTemac->iOldHandler );
    if( sc != RTEMS_SUCCESSFUL )
    {
      xilTemac->iOldHandler = 0;
      printk("%s: Could not set interrupt vector for interface '%s' opb_intc_set_vector ret: %d\n", DRIVER_PREFIX, xilTemac->iUnitName, sc );
      assert(0);
    }
#else
    {
      rtems_irq_connect_data IrqConnData;

      /*
       *get old irq handler
       */
      xilTemac->iOldHandler.name = xilTemac->iIsrVector;
      if (!BSP_get_current_rtems_irq_handler (&xilTemac->iOldHandler)) {
	xilTemac->iOldHandler.name = 0;
	printk("%s: Unable to detect previous Irq handler\n",DRIVER_PREFIX);
	rtems_fatal_error_occurred(1);
      }

      IrqConnData.on     = xilTemacIsrOn;
      IrqConnData.off    = xilTemacIsrOff;
      IrqConnData.isOn   = xilTemacIsrIsOn;
      IrqConnData.name   = xilTemac->iIsrVector;
      IrqConnData.hdl    = xilTemacIsr;
      IrqConnData.handle = xilTemac;

      if (!BSP_install_rtems_irq_handler (&IrqConnData)) {
	printk("%s: Unable to connect Irq handler\n",DRIVER_PREFIX);
	rtems_fatal_error_occurred(1);
      }
    }
#endif
    /* Enable promiscuous mode -- The temac only supports full duplex, which
       means we're plugged into a switch.  Thus promiscuous mode simply means
       we get all multicast addresses*/
    OUT32(base + XTE_EAFM_OFFSET, XTE_EAFM_EPPRM_MASK);

    /* Setup and enable receiver */
    rxc1 = XTE_ERXC1_RXFCS_MASK | XTE_ERXC1_RXEN_MASK | XTE_ERXC1_RXVLAN_MASK;
    OUT32(base + XTE_ERXC1_OFFSET, rxc1);

    /* Setup and enable transmitter */
    uint32_t txc = XTE_ETXC_TXEN_MASK | XTE_ETXC_TXVLAN_MASK;
    OUT32(base + XTE_ETXC_OFFSET, txc);

    /* Enable interrupts for temac */
    uint32_t ipier = IN32(base + XTE_IPIER_OFFSET);
    ipier |= (XTE_IPXR_XMIT_ERROR_MASK);
    ipier |= (XTE_IPXR_RECV_ERROR_MASK | XTE_IPXR_RECV_DONE_MASK);
    ipier |= (XTE_IPXR_AUTO_NEG_MASK);
    OUT32(base + XTE_IPIER_OFFSET, ipier);

    printk("%s: xiltemacStart, ipier: %08x\n",DRIVER_PREFIX, ipier);

    /* Enable device global interrutps */
    OUT32(base + XTE_DGIE_OFFSET, XTE_DGIE_ENABLE_MASK);
    ifp->if_flags |= IFF_RUNNING;
  }
}