root/drivers/video/fbdev/via/via_clock.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cle266_encode_pll
  2. k800_encode_pll
  3. vx855_encode_pll
  4. cle266_set_primary_pll_encoded
  5. k800_set_primary_pll_encoded
  6. cle266_set_secondary_pll_encoded
  7. k800_set_secondary_pll_encoded
  8. set_engine_pll_encoded
  9. cle266_set_primary_pll
  10. k800_set_primary_pll
  11. vx855_set_primary_pll
  12. cle266_set_secondary_pll
  13. k800_set_secondary_pll
  14. vx855_set_secondary_pll
  15. k800_set_engine_pll
  16. vx855_set_engine_pll
  17. set_primary_pll_state
  18. set_secondary_pll_state
  19. set_engine_pll_state
  20. set_primary_clock_state
  21. set_secondary_clock_state
  22. set_clock_source_common
  23. set_primary_clock_source
  24. set_secondary_clock_source
  25. dummy_set_clock_state
  26. dummy_set_clock_source
  27. dummy_set_pll_state
  28. dummy_set_pll
  29. noop_set_clock_state
  30. via_clock_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
   4  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
   5  * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
   6  */
   7 /*
   8  * clock and PLL management functions
   9  */
  10 
  11 #include <linux/kernel.h>
  12 #include <linux/via-core.h>
  13 
  14 #include "via_clock.h"
  15 #include "global.h"
  16 #include "debug.h"
  17 
  18 static const char *via_slap = "Please slap VIA Technologies to motivate them "
  19         "releasing full documentation for your platform!\n";
  20 
  21 static inline u32 cle266_encode_pll(struct via_pll_config pll)
  22 {
  23         return (pll.multiplier << 8)
  24                 | (pll.rshift << 6)
  25                 | pll.divisor;
  26 }
  27 
  28 static inline u32 k800_encode_pll(struct via_pll_config pll)
  29 {
  30         return ((pll.divisor - 2) << 16)
  31                 | (pll.rshift << 10)
  32                 | (pll.multiplier - 2);
  33 }
  34 
  35 static inline u32 vx855_encode_pll(struct via_pll_config pll)
  36 {
  37         return (pll.divisor << 16)
  38                 | (pll.rshift << 10)
  39                 | pll.multiplier;
  40 }
  41 
  42 static inline void cle266_set_primary_pll_encoded(u32 data)
  43 {
  44         via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */
  45         via_write_reg(VIASR, 0x46, data & 0xFF);
  46         via_write_reg(VIASR, 0x47, (data >> 8) & 0xFF);
  47         via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */
  48 }
  49 
  50 static inline void k800_set_primary_pll_encoded(u32 data)
  51 {
  52         via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */
  53         via_write_reg(VIASR, 0x44, data & 0xFF);
  54         via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF);
  55         via_write_reg(VIASR, 0x46, (data >> 16) & 0xFF);
  56         via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */
  57 }
  58 
  59 static inline void cle266_set_secondary_pll_encoded(u32 data)
  60 {
  61         via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */
  62         via_write_reg(VIASR, 0x44, data & 0xFF);
  63         via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF);
  64         via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */
  65 }
  66 
  67 static inline void k800_set_secondary_pll_encoded(u32 data)
  68 {
  69         via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */
  70         via_write_reg(VIASR, 0x4A, data & 0xFF);
  71         via_write_reg(VIASR, 0x4B, (data >> 8) & 0xFF);
  72         via_write_reg(VIASR, 0x4C, (data >> 16) & 0xFF);
  73         via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */
  74 }
  75 
  76 static inline void set_engine_pll_encoded(u32 data)
  77 {
  78         via_write_reg_mask(VIASR, 0x40, 0x01, 0x01); /* enable reset */
  79         via_write_reg(VIASR, 0x47, data & 0xFF);
  80         via_write_reg(VIASR, 0x48, (data >> 8) & 0xFF);
  81         via_write_reg(VIASR, 0x49, (data >> 16) & 0xFF);
  82         via_write_reg_mask(VIASR, 0x40, 0x00, 0x01); /* disable reset */
  83 }
  84 
  85 static void cle266_set_primary_pll(struct via_pll_config config)
  86 {
  87         cle266_set_primary_pll_encoded(cle266_encode_pll(config));
  88 }
  89 
  90 static void k800_set_primary_pll(struct via_pll_config config)
  91 {
  92         k800_set_primary_pll_encoded(k800_encode_pll(config));
  93 }
  94 
  95 static void vx855_set_primary_pll(struct via_pll_config config)
  96 {
  97         k800_set_primary_pll_encoded(vx855_encode_pll(config));
  98 }
  99 
 100 static void cle266_set_secondary_pll(struct via_pll_config config)
 101 {
 102         cle266_set_secondary_pll_encoded(cle266_encode_pll(config));
 103 }
 104 
 105 static void k800_set_secondary_pll(struct via_pll_config config)
 106 {
 107         k800_set_secondary_pll_encoded(k800_encode_pll(config));
 108 }
 109 
 110 static void vx855_set_secondary_pll(struct via_pll_config config)
 111 {
 112         k800_set_secondary_pll_encoded(vx855_encode_pll(config));
 113 }
 114 
 115 static void k800_set_engine_pll(struct via_pll_config config)
 116 {
 117         set_engine_pll_encoded(k800_encode_pll(config));
 118 }
 119 
 120 static void vx855_set_engine_pll(struct via_pll_config config)
 121 {
 122         set_engine_pll_encoded(vx855_encode_pll(config));
 123 }
 124 
 125 static void set_primary_pll_state(u8 state)
 126 {
 127         u8 value;
 128 
 129         switch (state) {
 130         case VIA_STATE_ON:
 131                 value = 0x20;
 132                 break;
 133         case VIA_STATE_OFF:
 134                 value = 0x00;
 135                 break;
 136         default:
 137                 return;
 138         }
 139 
 140         via_write_reg_mask(VIASR, 0x2D, value, 0x30);
 141 }
 142 
 143 static void set_secondary_pll_state(u8 state)
 144 {
 145         u8 value;
 146 
 147         switch (state) {
 148         case VIA_STATE_ON:
 149                 value = 0x08;
 150                 break;
 151         case VIA_STATE_OFF:
 152                 value = 0x00;
 153                 break;
 154         default:
 155                 return;
 156         }
 157 
 158         via_write_reg_mask(VIASR, 0x2D, value, 0x0C);
 159 }
 160 
 161 static void set_engine_pll_state(u8 state)
 162 {
 163         u8 value;
 164 
 165         switch (state) {
 166         case VIA_STATE_ON:
 167                 value = 0x02;
 168                 break;
 169         case VIA_STATE_OFF:
 170                 value = 0x00;
 171                 break;
 172         default:
 173                 return;
 174         }
 175 
 176         via_write_reg_mask(VIASR, 0x2D, value, 0x03);
 177 }
 178 
 179 static void set_primary_clock_state(u8 state)
 180 {
 181         u8 value;
 182 
 183         switch (state) {
 184         case VIA_STATE_ON:
 185                 value = 0x20;
 186                 break;
 187         case VIA_STATE_OFF:
 188                 value = 0x00;
 189                 break;
 190         default:
 191                 return;
 192         }
 193 
 194         via_write_reg_mask(VIASR, 0x1B, value, 0x30);
 195 }
 196 
 197 static void set_secondary_clock_state(u8 state)
 198 {
 199         u8 value;
 200 
 201         switch (state) {
 202         case VIA_STATE_ON:
 203                 value = 0x80;
 204                 break;
 205         case VIA_STATE_OFF:
 206                 value = 0x00;
 207                 break;
 208         default:
 209                 return;
 210         }
 211 
 212         via_write_reg_mask(VIASR, 0x1B, value, 0xC0);
 213 }
 214 
 215 static inline u8 set_clock_source_common(enum via_clksrc source, bool use_pll)
 216 {
 217         u8 data = 0;
 218 
 219         switch (source) {
 220         case VIA_CLKSRC_X1:
 221                 data = 0x00;
 222                 break;
 223         case VIA_CLKSRC_TVX1:
 224                 data = 0x02;
 225                 break;
 226         case VIA_CLKSRC_TVPLL:
 227                 data = 0x04; /* 0x06 should be the same */
 228                 break;
 229         case VIA_CLKSRC_DVP1TVCLKR:
 230                 data = 0x0A;
 231                 break;
 232         case VIA_CLKSRC_CAP0:
 233                 data = 0xC;
 234                 break;
 235         case VIA_CLKSRC_CAP1:
 236                 data = 0x0E;
 237                 break;
 238         }
 239 
 240         if (!use_pll)
 241                 data |= 1;
 242 
 243         return data;
 244 }
 245 
 246 static void set_primary_clock_source(enum via_clksrc source, bool use_pll)
 247 {
 248         u8 data = set_clock_source_common(source, use_pll) << 4;
 249         via_write_reg_mask(VIACR, 0x6C, data, 0xF0);
 250 }
 251 
 252 static void set_secondary_clock_source(enum via_clksrc source, bool use_pll)
 253 {
 254         u8 data = set_clock_source_common(source, use_pll);
 255         via_write_reg_mask(VIACR, 0x6C, data, 0x0F);
 256 }
 257 
 258 static void dummy_set_clock_state(u8 state)
 259 {
 260         printk(KERN_INFO "Using undocumented set clock state.\n%s", via_slap);
 261 }
 262 
 263 static void dummy_set_clock_source(enum via_clksrc source, bool use_pll)
 264 {
 265         printk(KERN_INFO "Using undocumented set clock source.\n%s", via_slap);
 266 }
 267 
 268 static void dummy_set_pll_state(u8 state)
 269 {
 270         printk(KERN_INFO "Using undocumented set PLL state.\n%s", via_slap);
 271 }
 272 
 273 static void dummy_set_pll(struct via_pll_config config)
 274 {
 275         printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap);
 276 }
 277 
 278 static void noop_set_clock_state(u8 state)
 279 {
 280 }
 281 
 282 void via_clock_init(struct via_clock *clock, int gfx_chip)
 283 {
 284         switch (gfx_chip) {
 285         case UNICHROME_CLE266:
 286         case UNICHROME_K400:
 287                 clock->set_primary_clock_state = dummy_set_clock_state;
 288                 clock->set_primary_clock_source = dummy_set_clock_source;
 289                 clock->set_primary_pll_state = dummy_set_pll_state;
 290                 clock->set_primary_pll = cle266_set_primary_pll;
 291 
 292                 clock->set_secondary_clock_state = dummy_set_clock_state;
 293                 clock->set_secondary_clock_source = dummy_set_clock_source;
 294                 clock->set_secondary_pll_state = dummy_set_pll_state;
 295                 clock->set_secondary_pll = cle266_set_secondary_pll;
 296 
 297                 clock->set_engine_pll_state = dummy_set_pll_state;
 298                 clock->set_engine_pll = dummy_set_pll;
 299                 break;
 300         case UNICHROME_K800:
 301         case UNICHROME_PM800:
 302         case UNICHROME_CN700:
 303         case UNICHROME_CX700:
 304         case UNICHROME_CN750:
 305         case UNICHROME_K8M890:
 306         case UNICHROME_P4M890:
 307         case UNICHROME_P4M900:
 308         case UNICHROME_VX800:
 309                 clock->set_primary_clock_state = set_primary_clock_state;
 310                 clock->set_primary_clock_source = set_primary_clock_source;
 311                 clock->set_primary_pll_state = set_primary_pll_state;
 312                 clock->set_primary_pll = k800_set_primary_pll;
 313 
 314                 clock->set_secondary_clock_state = set_secondary_clock_state;
 315                 clock->set_secondary_clock_source = set_secondary_clock_source;
 316                 clock->set_secondary_pll_state = set_secondary_pll_state;
 317                 clock->set_secondary_pll = k800_set_secondary_pll;
 318 
 319                 clock->set_engine_pll_state = set_engine_pll_state;
 320                 clock->set_engine_pll = k800_set_engine_pll;
 321                 break;
 322         case UNICHROME_VX855:
 323         case UNICHROME_VX900:
 324                 clock->set_primary_clock_state = set_primary_clock_state;
 325                 clock->set_primary_clock_source = set_primary_clock_source;
 326                 clock->set_primary_pll_state = set_primary_pll_state;
 327                 clock->set_primary_pll = vx855_set_primary_pll;
 328 
 329                 clock->set_secondary_clock_state = set_secondary_clock_state;
 330                 clock->set_secondary_clock_source = set_secondary_clock_source;
 331                 clock->set_secondary_pll_state = set_secondary_pll_state;
 332                 clock->set_secondary_pll = vx855_set_secondary_pll;
 333 
 334                 clock->set_engine_pll_state = set_engine_pll_state;
 335                 clock->set_engine_pll = vx855_set_engine_pll;
 336                 break;
 337 
 338         }
 339 
 340         if (machine_is_olpc()) {
 341                 /* The OLPC XO-1.5 cannot suspend/resume reliably if the
 342                  * IGA1/IGA2 clocks are set as on or off (memory rot
 343                  * occasionally happens during suspend under such
 344                  * configurations).
 345                  *
 346                  * The only known stable scenario is to leave this bits as-is,
 347                  * which in their default states are documented to enable the
 348                  * clock only when it is needed.
 349                  */
 350                 clock->set_primary_clock_state = noop_set_clock_state;
 351                 clock->set_secondary_clock_state = noop_set_clock_state;
 352         }
 353 }

/* [<][>][^][v][top][bottom][index][help] */