コード例 #1
0
ファイル: cmd_qlm.c プロジェクト: disdi/u-boot-cavium
enum command_ret_t
do_qlm_clock(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	int qlm;

	if (argc < 2)
		return CMD_RET_USAGE;

	qlm = simple_strtoul(argv[1], NULL, 10);

	printf("QLM %d clock speed: %d\n", qlm, cvmx_qlm_measure_clock(qlm));

	return CMD_RET_SUCCESS;
}
コード例 #2
0
ファイル: cvmx-qlm.c プロジェクト: xtra72/s805
/**
 * @INTERNAL
 * Decrement the MPLL Multiplier for the DLM as per Errata G-20669
 *
 * @param qlm            DLM to configure
 * @param baud_mhz       Speed of the DLM configured at
 * @param old_multiplier MPLL_MULTIPLIER value to decrement
 */
void __cvmx_qlm_set_mult(int qlm, int baud_mhz, int old_multiplier)
{
	cvmx_gserx_dlmx_mpll_multiplier_t mpll_multiplier;
	uint64_t meas_refclock, mult;

	if (!OCTEON_IS_MODEL(OCTEON_CN70XX))
		return;

	if (qlm == -1)
		return;

	meas_refclock = cvmx_qlm_measure_clock(qlm);
	if (meas_refclock == 0) {
		cvmx_warn("DLM%d: Reference clock not running\n", qlm);
		return;
	}

	mult = (uint64_t)baud_mhz * 1000000 + (meas_refclock/2);
	mult /= meas_refclock;

#ifdef CVMX_BUILD_FOR_UBOOT
	/* For simulator just write the multiplier directly, to make it
	   faster to boot. */
	if (gd->arch.board_desc.board_type == CVMX_BOARD_TYPE_SIM) {
		cvmx_write_csr(CVMX_GSERX_DLMX_MPLL_MULTIPLIER(qlm, 0), mult);
		return;
	}
#endif

	/* 6. Decrease MPLL_MULTIPLIER by one continually until it reaches
	     the desired long-term setting, ensuring that each MPLL_MULTIPLIER
	     value is constant for at least 1 msec before changing to the next
	     value. The desired long-term setting is as indicated in HRM tables
	     21-1, 21-2, and 21-3. This is not required with the HRM
	     sequence. */
	do {
		mpll_multiplier.u64 = cvmx_read_csr(CVMX_GSERX_DLMX_MPLL_MULTIPLIER(qlm, 0));
		mpll_multiplier.s.mpll_multiplier = --old_multiplier;
		cvmx_write_csr(CVMX_GSERX_DLMX_MPLL_MULTIPLIER(qlm, 0), mpll_multiplier.u64);
		/* Wait for 1 ms */
		cvmx_wait_usec(1000);
	} while (old_multiplier > (int)mult);
}
コード例 #3
0
ファイル: sff7000_board.c プロジェクト: disdi/u-boot-cavium
int checkboard(void)
{
	int clk_to_use = 0;	/* Clock used for DLM0 */
	int val;

	val = pca953x_get_val(0, 0x20);

	/* Print it early so switches are in order */
	if (val & 1) {	/* DLM0_SEL */
		puts("SW4-1 on: RXAUI (10G) port selected\n");
		octeon_configure_qlm(0, 6250, CVMX_QLM_MODE_RXAUI,
				     0, 0, 2, 2);
	} else {
		puts("SW4-1 off: QSGMII ports selected\n");
		octeon_configure_qlm(0, 2500, CVMX_QLM_MODE_QSGMII_QSGMII,
				     0, 0, 1, 1);
	}

	if (val & 2) {	/* DLM1_SEL */
		if (val & 4) {
			puts("SW4-2 on, SW4-3 off: PCIe 1x2 mode selected\n");
			octeon_configure_qlm(1, 5000, CVMX_QLM_MODE_PCIE_1X2,
					     1, 1, 0, 0);
		} else {
			int host_mode = cvmx_pcie_is_host_mode(0);
			printf("SW4-2 on, SW4-3 on: PCIe 1x4 %s mode selected\n",
			       host_mode ? "host" : "target");
			/* For PCIe target mode we need to use clock 1 for DLM0
			 * since in this case clock 0 is coming from the PCIe
			 * host.  Also, there's no need to configure the DLM
			 * if we're in PCIe target (endpoint) mode.
			 */
			if (host_mode)
				octeon_configure_qlm(1, 5000,
						     CVMX_QLM_MODE_PCIE,
						     1, 1, clk_to_use, 0);
			else
				clk_to_use = 1;

		}
	} else {
		puts("SW4-2 off: mini-PCIe slots selected\n");
		octeon_configure_qlm(1, 5000, CVMX_QLM_MODE_PCIE_2X1, 1, 1, 0, 0);
	}

	if (val & 4) {	/* DLM2_SEL */
		puts("SW4-3 on: SATA ports selected\n");
		octeon_configure_qlm(2, 3125, CVMX_QLM_MODE_SATA_2X1,
				     0, 0, 1, 1);
	}
	if (val & 8)
		puts("SW4-4 on: PCM mode selected, SPI NOR disabled\n");
	else
		puts("SW4-4 off: SPI NOR enabled\n");

	printf("SW 1-8 is %s, %s selected as slot 1.\n",
	       val & 0x10 ? "on" : "off",
	       val & 0x10 ? "internal eMMC flash" : "external SD/MMC slot");

	debug("qlm 0 reference clock: %llu\n", cvmx_qlm_measure_clock(0));
	debug("qlm 1 reference clock: %llu\n", cvmx_qlm_measure_clock(1));
	debug("qlm 2 reference clock: %llu\n", cvmx_qlm_measure_clock(2));

	return 0;
}
コード例 #4
0
ファイル: cvmx-qlm.c プロジェクト: xtra72/s805
/**
 * Get the speed (Gbaud) of the QLM in Mhz.
 *
 * @param qlm    QLM to examine
 *
 * @return Speed in Mhz
 */
int cvmx_qlm_get_gbaud_mhz(int qlm)
{
	if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
		if (qlm == 2) {
			cvmx_gmxx_inf_mode_t inf_mode;
			inf_mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(0));
			switch (inf_mode.s.speed) {
			case 0:
				return 5000;	/* 5     Gbaud */
			case 1:
				return 2500;	/* 2.5   Gbaud */
			case 2:
				return 2500;	/* 2.5   Gbaud */
			case 3:
				return 1250;	/* 1.25  Gbaud */
			case 4:
				return 1250;	/* 1.25  Gbaud */
			case 5:
				return 6250;	/* 6.25  Gbaud */
			case 6:
				return 5000;	/* 5     Gbaud */
			case 7:
				return 2500;	/* 2.5   Gbaud */
			case 8:
				return 3125;	/* 3.125 Gbaud */
			case 9:
				return 2500;	/* 2.5   Gbaud */
			case 10:
				return 1250;	/* 1.25  Gbaud */
			case 11:
				return 5000;	/* 5     Gbaud */
			case 12:
				return 6250;	/* 6.25  Gbaud */
			case 13:
				return 3750;	/* 3.75  Gbaud */
			case 14:
				return 3125;	/* 3.125 Gbaud */
			default:
				return 0;	/* Disabled */
			}
		} else {
			cvmx_sriox_status_reg_t status_reg;
			status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(qlm));
			if (status_reg.s.srio) {
				cvmx_sriomaintx_port_0_ctl2_t sriomaintx_port_0_ctl2;
				sriomaintx_port_0_ctl2.u32 = cvmx_read_csr(CVMX_SRIOMAINTX_PORT_0_CTL2(qlm));
				switch (sriomaintx_port_0_ctl2.s.sel_baud) {
				case 1:
					return 1250;	/* 1.25  Gbaud */
				case 2:
					return 2500;	/* 2.5   Gbaud */
				case 3:
					return 3125;	/* 3.125 Gbaud */
				case 4:
					return 5000;	/* 5     Gbaud */
				case 5:
					return 6250;	/* 6.250 Gbaud */
				default:
					return 0;	/* Disabled */
				}
			} else {
				cvmx_pciercx_cfg032_t pciercx_cfg032;
				pciercx_cfg032.u32 = cvmx_read_csr(CVMX_PCIERCX_CFG032(qlm));
				switch (pciercx_cfg032.s.ls) {
				case 1:
					return 2500;
				case 2:
					return 5000;
				case 4:
					return 8000;
				default:
					{
						cvmx_mio_rst_boot_t mio_rst_boot;
						mio_rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
						if ((qlm == 0) && mio_rst_boot.s.qlm0_spd == 0xf)
							return 0;
						if ((qlm == 1) && mio_rst_boot.s.qlm1_spd == 0xf)
							return 0;
						return 5000;	/* Best guess I can make */
					}
				}
			}
		}
	} else if (OCTEON_IS_OCTEON2()) {
		cvmx_mio_qlmx_cfg_t qlm_cfg;

		qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(qlm));
		switch (qlm_cfg.s.qlm_spd) {
		case 0:
			return 5000;	/* 5     Gbaud */
		case 1:
			return 2500;	/* 2.5   Gbaud */
		case 2:
			return 2500;	/* 2.5   Gbaud */
		case 3:
			return 1250;	/* 1.25  Gbaud */
		case 4:
			return 1250;	/* 1.25  Gbaud */
		case 5:
			return 6250;	/* 6.25  Gbaud */
		case 6:
			return 5000;	/* 5     Gbaud */
		case 7:
			return 2500;	/* 2.5   Gbaud */
		case 8:
			return 3125;	/* 3.125 Gbaud */
		case 9:
			return 2500;	/* 2.5   Gbaud */
		case 10:
			return 1250;	/* 1.25  Gbaud */
		case 11:
			return 5000;	/* 5     Gbaud */
		case 12:
			return 6250;	/* 6.25  Gbaud */
		case 13:
			return 3750;	/* 3.75  Gbaud */
		case 14:
			return 3125;	/* 3.125 Gbaud */
		default:
			return 0;	/* Disabled */
		}
	} else if (OCTEON_IS_MODEL(OCTEON_CN70XX)) {
		cvmx_gserx_dlmx_mpll_multiplier_t mpll_multiplier;
		uint64_t meas_refclock;
		uint64_t freq;

		/* Measure the reference clock */
		meas_refclock = cvmx_qlm_measure_clock(qlm);
		/* Multiply to get the final frequency */
		mpll_multiplier.u64 = cvmx_read_csr(CVMX_GSERX_DLMX_MPLL_MULTIPLIER(qlm, 0));
		freq = meas_refclock * mpll_multiplier.s.mpll_multiplier;
		freq = (freq + 500000) / 1000000;
		return freq;
	}
	return 0;
}