/* freq: pclk/50/16/65536 ~ pclk/50/16 * if pclk = 50MHz, freq is 1Hz to 62500Hz * human ear : 20Hz~ 20000Hz */ static void PWM_Set_Freq( unsigned long freq ) { unsigned long tcon; unsigned long tcnt; unsigned long tcfg1; unsigned long tcfg0; struct clk *clk_p; unsigned long pclk; unsigned tmp; printk ("Freq is %d",freq); tmp = readl(S3C64XX_GPFCON);//PWM out use GPF15 here tmp &=~(0x3U << 30);// No use Timer0,use Timer1 here tmp |= (0x2U << 30); writel(tmp, S3C64XX_GPFCON);// Set hightest bit is '10' to pwm out tcon = __raw_readl(S3C_TCON); tcfg1 = __raw_readl(S3C_TCFG1); tcfg0 = __raw_readl(S3C_TCFG0); //prescaler = 50 tcfg0 &= ~S3C_TCFG_PRESCALER0_MASK; tcfg0 |= (50 - 1); //mux = 1/16 tcfg1 &= ~S3C_TCFG1_MUX1_MASK; tcfg1 |= S3C_TCFG1_MUX1_DIV16; __raw_writel(tcfg1, S3C_TCFG1); __raw_writel(tcfg0, S3C_TCFG0); clk_p = clk_get(NULL, "pclk"); pclk = clk_get_rate(clk_p); tcnt = (pclk/50/16)/freq; // printk ("pclk is %d\n", pclk); __raw_writel(tcnt, S3C_TCNTB(1)); __raw_writel(tcnt/2, S3C_TCMPB(1)); tcon &= ~(0xf << 8); tcon |= (0xb << 8); // set 11-8 bit of S3C_TCON is '1011' . auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 1 __raw_writel(tcon, S3C_TCON); tcon &= ~(2 << 8); //set set 11-8 bit of S3C_TCON is '1001' __raw_writel(tcon, S3C_TCON); }
/* freq: pclk/50/16/65536 ~ pclk/50/16 * if pclk = 50MHz, freq is 1Hz to 62500Hz * human ear : 20Hz~ 20000Hz */ static void PWM_Set_Freq( unsigned long freq ) { unsigned long tcon; unsigned long tcnt; unsigned long tcfg1; unsigned long tcfg0; struct clk *clk_p; unsigned long pclk; unsigned int tmp; /* Begin Commented Out unsigned int current_value = readl(S3C64XX_GPFCON); End Commented Out */ tmp = readl(S3C64XX_GPFCON); tmp &= ~(0x3U << 28); // turn off PWM0 and PWM1 tmp |= (0x2U << 28); // turn on PWM0 writel(tmp, S3C64XX_GPFCON); /* Begin Commented Out printk( KERN_ERR "ML: read current value (0x%08x)\n", current_value ) ; End Commented Out */ tcon = __raw_readl(S3C_TCON); tcfg1 = __raw_readl(S3C_TCFG1); tcfg0 = __raw_readl(S3C_TCFG0); //prescaler = 50 tcfg0 &= ~S3C_TCFG_PRESCALER0_MASK; tcfg0 |= (50 - 1); //mux = 1/16 tcfg1 &= ~S3C_TCFG1_MUX0_MASK; tcfg1 |= S3C_TCFG1_MUX0_DIV16; __raw_writel(tcfg1, S3C_TCFG1); __raw_writel(tcfg0, S3C_TCFG0); clk_p = clk_get(NULL, "pclk"); pclk = clk_get_rate(clk_p); tcnt = (pclk/50/16)/freq; __raw_writel(tcnt, S3C_TCNTB(0)); __raw_writel(tcnt/2, S3C_TCMPB(0)); tcon &= ~0x1f; tcon |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0 __raw_writel(tcon, S3C_TCON); tcon &= ~2; //clear manual update bit __raw_writel(tcon, S3C_TCON); }
/* freq: pclk/50/16/65536 ~ pclk/50/16 * if pclk = 50MHz, freq is 1Hz to 62500Hz * human ear : 20Hz~ 20000Hz */ static void PWM_Set_Freq( unsigned long freq ) { #if 0 unsigned long tcon; unsigned long tcnt; unsigned long tcfg1; unsigned long tcfg0; struct clk *clk_p; unsigned long pclk; unsigned tmp; tmp = readl(S3C64XX_GPFCON); //tmp &= ~(0x3U << 28); //tmp |= (0x2U << 28); tmp &=~(0x3U << 30); tmp |= (0x2U << 30); writel(tmp, S3C64XX_GPFCON); tcon = __raw_readl(S3C_TCON); tcfg1 = __raw_readl(S3C_TCFG1); tcfg0 = __raw_readl(S3C_TCFG0); //prescaler = 50 tcfg0 &= ~S3C_TCFG_PRESCALER0_MASK; tcfg0 |= (50 - 1); //mux = 1/16 tcfg1 &= ~S3C_TCFG1_MUX0_MASK; tcfg1 |= S3C_TCFG1_MUX0_DIV16; __raw_writel(tcfg1, S3C_TCFG1); __raw_writel(tcfg0, S3C_TCFG0); clk_p = clk_get(NULL, "pclk"); pclk = clk_get_rate(clk_p); tcnt = (pclk/50/16)/freq; __raw_writel(tcnt, S3C_TCNTB(0)); __raw_writel(tcnt/2, S3C_TCMPB(0)); tcon &= ~0x1f; tcon |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0 __raw_writel(tcon, S3C_TCON); tcon &= ~2; //clear manual update bit __raw_writel(tcon, S3C_TCON); #endif }
static void sec_tick_timer_start(unsigned long load_val, int autoreset) { unsigned long tcon; unsigned long tcnt; unsigned long tcfg1; unsigned long tcfg0; unsigned long tcstat; tcon = __raw_readl(S3C_TCON); tcfg1 = __raw_readl(S3C_TCFG1); tcfg0 = __raw_readl(S3C_TCFG0); tcstat = __raw_readl(S3C_TINT_CSTAT); tcstat |= 0x10; __raw_writel(tcstat, S3C_TINT_CSTAT); tcnt = load_val; tcnt--; __raw_writel(tcnt, S3C_TCNTB(4)); tcfg1 &= ~S3C_TCFG1_MUX4_MASK; tcfg1 |= S3C_TCFG1_MUX4_DIV1; tcfg0 &= ~S3C_TCFG_PRESCALER1_MASK; tcfg0 |= (0) << S3C_TCFG_PRESCALER1_SHIFT; __raw_writel(tcfg1, S3C_TCFG1); __raw_writel(tcfg0, S3C_TCFG0); tcon &= ~(7<<20); tcon |= S3C_TCON_T4MANUALUPD; if (autoreset) tcon |= S3C_TCON_T4RELOAD; __raw_writel(tcon, S3C_TCON); /* start the timer running */ tcon |= S3C_TCON_T4START; tcon &= ~S3C_TCON_T4MANUALUPD; __raw_writel(tcon, S3C_TCON); }
static void sec_sched_timer_start(unsigned long load_val, int autoreset) { unsigned long tcon; unsigned long tcnt; unsigned long tcfg1; unsigned long tcfg0; unsigned long tcstat; tcstat = __raw_readl(S3C_TINT_CSTAT); tcstat |= 0x04; __raw_writel(tcstat, S3C_TINT_CSTAT); tcon = __raw_readl(S3C_TCON); tcfg1 = __raw_readl(S3C_TCFG1); tcfg0 = __raw_readl(S3C_TCFG0); tcnt = load_val; tcnt--; __raw_writel(tcnt, S3C_TCNTB(2)); __raw_writel(tcnt, S3C_TCMPB(2)); tcon &= ~(0x0b<<12); if (autoreset) tcon |= S3C_TCON_T2RELOAD; tcon |= S3C_TCON_T2MANUALUPD; __raw_writel(tcon, S3C_TCON); /* start the timer running */ tcon |= S3C_TCON_T2START; tcon &= ~S3C_TCON_T2MANUALUPD; __raw_writel(tcon, S3C_TCON); }
int S5PC11X_timer_setup (int channel, int usec, unsigned long g_tcnt, unsigned long g_tcmp) { unsigned long tcon; unsigned long tcnt; unsigned long tcmp; unsigned long tcfg1; unsigned long tcfg0; unsigned long pclk; struct clk *clk; printk("\nPWM channel %d set g_tcnt = %ld, g_tcmp = %ld \n", channel, g_tcnt, g_tcmp); tcnt = 0xffffffff; /* default value for tcnt */ /* read the current timer configuration bits */ tcon = __raw_readl(S3C_TCON); tcfg1 = __raw_readl(S3C_TCFG1); tcfg0 = __raw_readl(S3C_TCFG0); clk = clk_get(NULL, "timers"); if (IS_ERR(clk)) panic("failed to get clock for pwm timer"); clk_enable(clk); pclk = clk_get_rate(clk); /* configure clock tick */ switch(channel) { case 0: /* set gpio as PWM TIMER0 to signal output*/ s3c_gpio_cfgpin(S5PC11X_GPD(0), S5PC11X_GPD0_TOUT_0); gpio_set_value(S5PC11X_GPD(0), 0); tcfg1 &= ~S3C_TCFG1_MUX0_MASK; tcfg1 |= S3C_TCFG1_MUX1_DIV2; tcfg0 &= ~S3C_TCFG_PRESCALER0_MASK; tcfg0 |= (PRESCALER) << S3C_TCFG_PRESCALER0_SHIFT; tcon &= ~(7<<0); tcon |= S3C_TCON_T0RELOAD; break; case 1: /* set gpio as PWM TIMER1 to signal output*/ s3c_gpio_cfgpin(S5PC11X_GPD(1), S5PC11X_GPD1_TOUT_1); gpio_set_value(S5PC11X_GPD(1), 0); tcfg1 &= ~S3C_TCFG1_MUX1_MASK; tcfg1 |= S3C_TCFG1_MUX1_DIV2; tcfg0 &= ~S3C_TCFG_PRESCALER0_MASK; tcfg0 |= (PRESCALER) << S3C_TCFG_PRESCALER0_SHIFT; tcon &= ~(7<<8); tcon |= S3C_TCON_T1RELOAD; break; case 2: /* set gpio as PWM TIMER2 to signal output*/ s3c_gpio_cfgpin(S5PC11X_GPD(2), S5PC11X_GPD0_TOUT_0); gpio_set_value(S5PC11X_GPD(2), 0); tcfg1 &= ~S3C_TCFG1_MUX2_MASK; tcfg1 |= S3C_TCFG1_MUX2_DIV2; tcfg0 &= ~S3C_TCFG_PRESCALER1_MASK; tcfg0 |= (PRESCALER) << S3C_TCFG_PRESCALER1_SHIFT; tcon &= ~(7<<12); tcon |= S3C_TCON_T2RELOAD; break; case 3: tcfg1 &= ~S3C_TCFG1_MUX3_MASK; tcfg1 |= S3C_TCFG1_MUX3_DIV2; tcfg0 &= ~S3C_TCFG_PRESCALER1_MASK; tcfg0 |= (PRESCALER) << S3C_TCFG_PRESCALER1_SHIFT; tcon &= ~(7<<16); tcon |= S3C_TCON_T3RELOAD; break; case 4: tcfg1 &= ~S3C_TCFG1_MUX4_MASK; tcfg1 |= S3C_TCFG1_MUX4_DIV2; tcfg0 &= ~S3C_TCFG_PRESCALER1_MASK; tcfg0 |= (PRESCALER) << S3C_TCFG_PRESCALER1_SHIFT; tcon &= ~(7<<20); tcon |= S3C_TCON_T3RELOAD; break; } __raw_writel(tcfg1, S3C_TCFG1); __raw_writel(tcfg0, S3C_TCFG0); __raw_writel(tcon, S3C_TCON); /*tcnt = 160; __raw_writel(tcnt, S3C_TCNTB(channel)); tcmp = 110; __raw_writel(tcmp, S3C_TCMPB(channel));*/ switch(channel) { case 0: tcon |= S3C_TCON_T0MANUALUPD; break; case 1: tcon |= S3C_TCON_T1MANUALUPD; break; case 2: tcon |= S3C_TCON_T2MANUALUPD; break; case 3: tcon |= S3C_TCON_T3MANUALUPD; break; case 4: tcon |= S3C_TCON_T4MANUALUPD; break; } __raw_writel(tcon, S3C_TCON); tcnt = g_tcnt; __raw_writel(tcnt, S3C_TCNTB(channel)); tcmp = g_tcmp; __raw_writel(tcmp, S3C_TCMPB(channel)); /* start the timer running */ S5PC11X_pwm_start ( channel); return 0; }
int s3c6400_timer_setup (int channel, int usec, unsigned long g_tcnt, unsigned long g_tcmp) { unsigned long tcon; unsigned long tcnt; unsigned long tcmp; unsigned long tcfg1; unsigned long tcfg0; unsigned long pclk; struct clk *clk; printk("PWM channel %d set g_tcnt = %ld, g_tcmp = %ld \n", channel, g_tcnt, g_tcmp); tcnt = 0xffffffff; /* default value for tcnt */ /* read the current timer configuration bits */ tcon = __raw_readl(S3C_TCON); tcfg1 = __raw_readl(S3C_TCFG1); tcfg0 = __raw_readl(S3C_TCFG0); clk = clk_get(NULL, "timers"); if (IS_ERR(clk)) panic("failed to get clock for pwm timer"); clk_enable(clk); pclk = clk_get_rate(clk); /* configure clock tick */ switch(channel) { case 0: /* set gpio as PWM TIMER0 to signal output*/ s3c_gpio_cfgpin(S3C_GPF14, S3C_GPF14_PWM_TOUT0); s3c_gpio_setpin(S3C_GPF14, 0); tcfg1 &= ~S3C_TCFG1_MUX0_MASK; tcfg1 |= S3C_TCFG1_MUX0_DIV2; tcfg0 &= ~S3C_TCFG_PRESCALER0_MASK; tcfg0 |= (PRESCALER) << S3C_TCFG_PRESCALER0_SHIFT; tcon &= ~(7<<0); tcon |= S3C_TCON_T0RELOAD; break; case 1: /* set gpio as PWM TIMER1 to signal output*/ s3c_gpio_cfgpin(S3C_GPF15, S3C_GPF15_PWM_TOUT1); s3c_gpio_setpin(S3C_GPF15, 0); tcfg1 &= ~S3C_TCFG1_MUX1_MASK; tcfg1 |= S3C_TCFG1_MUX1_DIV2; tcfg0 &= ~S3C_TCFG_PRESCALER0_MASK; tcfg0 |= (PRESCALER) << S3C_TCFG_PRESCALER0_SHIFT; tcon &= ~(7<<8); tcon |= S3C_TCON_T1RELOAD; break; case 2: tcfg1 &= ~S3C_TCFG1_MUX2_MASK; tcfg1 |= S3C_TCFG1_MUX2_DIV2; tcfg0 &= ~S3C_TCFG_PRESCALER1_MASK; tcfg0 |= (PRESCALER) << S3C_TCFG_PRESCALER1_SHIFT; tcon &= ~(7<<12); tcon |= S3C_TCON_T2RELOAD; break; case 3: tcfg1 &= ~S3C_TCFG1_MUX3_MASK; tcfg1 |= S3C_TCFG1_MUX3_DIV2; tcfg0 &= ~S3C_TCFG_PRESCALER1_MASK; tcfg0 |= (PRESCALER) << S3C_TCFG_PRESCALER1_SHIFT; tcon &= ~(7<<16); tcon |= S3C_TCON_T3RELOAD; break; } #if 0 tcnt = (pclk / ((PRESCALER)*DIVIDER)) / usec; printk("s3c6400 pwm timer tcnt=0x%08lx, pclk=0x%08lx, PRESCALER=%d, DIVIDER=%d, usec=%d\n", tcnt, pclk, PRESCALER, DIVIDER, usec); /* timers reload after counting zero, so reduce the count by 1 */ tcnt--; #endif __raw_writel(tcfg1, S3C_TCFG1); __raw_writel(tcfg0, S3C_TCFG0); __raw_writel(tcon, S3C_TCON); tcnt = 160; #if 0 if (tcnt > 0xffffffff) { panic("setup_timer: HZ is too small, cannot configure timer!"); return 0; } #endif __raw_writel(tcnt, S3C_TCNTB(channel)); tcmp = 110; __raw_writel(tcmp, S3C_TCMPB(channel)); switch(channel) { case 0: tcon |= S3C_TCON_T0MANUALUPD; break; case 1: tcon |= S3C_TCON_T1MANUALUPD; break; case 2: tcon |= S3C_TCON_T2MANUALUPD; break; case 3: tcon |= S3C_TCON_T3MANUALUPD; break; } __raw_writel(tcon, S3C_TCON); tcnt = g_tcnt; __raw_writel(tcnt, S3C_TCNTB(channel)); tcmp = g_tcmp; __raw_writel(tcmp, S3C_TCMPB(channel)); /* start the timer running */ s3c6400_pwm_start ( channel); return 0; }